更新同一张表中的行

huangapple go评论47阅读模式
英文:

Update row in the same table

问题

我有一个表格1,看起来像这样:

EID      Hold        Source
3232     KLME         jame.k@gmail.com
         KLME         https://google.com
         EEME         david.e@gmail.com
         JJIN         Test@gmail.com
7232     JJIN         https://google.com

我只是想知道如何使用第一行来更新第二行的“Hold”为“KLME”。

例如,像这样:

EID      Hold        Source
3232     KLME         jame.k@gmail.com
3232     KLME         https://google.com
         EEME         david.e@gmail.com
7232     JJIN         Test@gmail.com
7232     JJIN         https://google.com

我有这个简单的脚本,但出现了一个问题,我得到了不同用户的不同EID,而不是正确的EID。

英文:

I have Table 1 that look something like this

EID      Hold        Source
3232     KLME         jame.k@gmail.com
         KLME         https://google.com
         EEME         david.e@gmail.com
         JJIN         Test@gmail.com
7232     JJIN         https://google.com

I'm just wondering how can I update the second row of hold "KLME" using the first row.

example like this

EID      Hold        Source
3232     KLME         jame.k@gmail.com
3232     KLME         https://google.com
         EEME         david.e@gmail.com
7232     JJIN         Test@gmail.com
7232     JJIN         https://google.com

UPDATE Test_Table 
SET EID = (
    SELECT TOP 1 Test_Table.EID
    FROM Test_Table 
    WHERE Test_Table.Hold = Test_Table.Hold
    AND Test_Table.EID <> '' OR Test_Table.EID <> NULL
)

I have this simple script but I'm getting a different EID from different user instead of the correct EID for some reason.

答案1

得分: 2

使用 MAX()

UPDATE Test_Table 
SET EID = (
    SELECT MAX(EID)
    FROM Test_Table a
    WHERE a.Hold = Test_Table.Hold
)

请注意,您无需过滤空白或空值,因为 MAX 会忽略空值,而任何非空白值都大于空白。

另外,通过不添加 WHERE 子句到 UPDATE,您将自动纠正对于特定 Hold 而言 EID 不同的任何不一致情况。

英文:

Use MAX():

UPDATE Test_Table 
SET EID = (
    SELECT MAX(EID)
    FROM Test_Table a
    WHERE a.Hold = Test_Table.Hold
)

Note how you don't need to filter out blanks or nulls because MAX ignores nulls and any non-blank value is greater than blank.

Also, by not adding a WHERE clause to the UPDATE, you'll automatically correct any inconsistencies with EID being different for a given Hold.

答案2

得分: 2

您可以使用可更新的公共表达式(CTE)和窗口函数。 这样做的好处是表只被扫描一次。

WITH cte AS (
    SELECT *,
      OtherEID = MIN(NULLIF(tt.EID, '')) OVER (PARTITION BY tt.HOLD)
    FROM Test_Table tt
)
UPDATE cte
SET EID = OtherEID
WHERE (EID IS NULL OR EID = '')
  AND OtherEID IS NOT NULL;
英文:

You can use an updatable CTE and a window function. The benefit of this is that the table is only scanned once.

WITH cte AS (
    SELECT *,
      OtherEID = MIN(NULLIF(tt.EID, '')) OVER (PARTITION BY tt.HOLD)
    FROM Test_Table tt
)
UPDATE cte
SET EID = OtherEID
WHERE (EID IS NULL OR EID = '')
  AND OtherEID IS NOT NULL;

答案3

得分: 1

有很多问题出现在你的查询中。

  1. 你不能对null使用等于(或不等于)检查,必须使用 IS NOT NULL
  2. 你需要在你的 OR 条件周围加上括号,以获得正确的逻辑。
  3. 你实际上只需要更新缺少 EID 的行。

一个可能的解决方案,可以正确地更新行,并正确关联新值是

UPDATE t1 SET
  EID = (SELECT TOP 1 Test_Table.EID FROM Test_Table t2 WHERE t2.[Hold] = t1.[Hold] AND COALESCE(t2.EID, '') <> '')
FROM Test_Table t1
WHERE Test_Table.EID = '' OR Test_Table.EID IS NULL;
英文:

There is a lot going wrong with your query.

  1. You cannot use an equality (or inequality) check against null, you must use IS NOT NULL
  2. You need brackets around your ORed conditions to get the correct logic
  3. You really only need to update rows with a missing EID.

A possible solution which updates the correct rows, and correlates the new value correctly is

UPDATE t1 SET
  EID = (SELECT TOP 1 Test_Table.EID FROM Test_Table t2 WHERE t2.[Hold] = t1.[Hold] AND COALESCE(t2.EID,&#39;&#39;) &lt;&gt; &#39;&#39;)
FROM Test_Table t1
WHERE Test_Table.EID = &#39;&#39; OR Test_Table.EID IS NULL;

答案4

得分: 1

你可以使用group bymax()来实现,步骤如下:

首先按Hold获取最大的Eid:

select Hold, max(EID) as Eid
from Test_Table
group by Hold

然后在将其与你的表连接后进行更新:

update t
set Eid = S.Eid
from Test_Table t
inner join (
  select Hold, max(EID) as Eid
  from Test_Table
  group by Hold
) s on s.Hold = t.Hold
英文:

You can do it using group by and max() as follows :

First get the max(Eid) per Hold :

select Hold, max(EID) as Eid
from Test_Table
group by Hold

Then apply the update after joining it to your table:

update t
set Eid = S.Eid
from Test_Table t
inner join (
  select Hold, max(EID) as Eid
  from Test_Table
  group by Hold
) s on s.Hold = t.Hold

demo here

答案5

得分: 1

以下是您的数据的翻译部分:

创建表格 mytable(
   EID    整数  
  ,Hold   变量字符(20) 非空
  ,Source 变量字符(100) 非空
);
 mytable 插入数据(EID,Hold,Source)  
(3232,'KLME','jame.k@gmail.com'),
(NULL,'KLME','https://google.com'),
(NULL,'EEME','david.e@gmail.com'),
(NULL,'JJIN','Test@gmail.com'),
(7232,'JJIN','https://google.com');

使用以下查询:

更新 m1
设置 m1.EID=如果(m1.EID 是空的, m2.EID, m1.EID)
 mytable m1
加入 mytable m2
 m1.Hold=m2.Hold  m1.Source<>m2.Source 的条件下 

dbfiddle

或者更简单的方式:

更新 m1
设置 m1.EID=m2.EID
 mytable m1
加入 mytable m2
 m1.Hold=m2.Hold  m1.Source<>m2.Source  m1.EID 是空的条件下

dbfiddle

英文:

your data

CREATE TABLE mytable(
   EID    INTEGER  
  ,Hold   VARCHAR(20) NOT NULL
  ,Source VARCHAR(100) NOT NULL
);
INSERT INTO mytable(EID,Hold,Source) VALUES 
(3232,&#39;KLME&#39;,&#39;jame.k@gmail.com&#39;),
(NULL,&#39;KLME&#39;,&#39;https://google.com&#39;),
(NULL,&#39;EEME&#39;,&#39;david.e@gmail.com&#39;),
(NULL,&#39;JJIN&#39;,&#39;Test@gmail.com&#39;),
(7232,&#39;JJIN&#39;,&#39;https://google.com&#39;);

use following query

update m1
set m1.EID=iif(m1.EID is null,m2.EID,m1.EID)
from mytable m1
join mytable m2
on m1.Hold=m2.Hold and m1.Source&lt;&gt;m2.Source 

dbfiddle

or more simply

update m1
set m1.EID=m2.EID
from mytable m1
join mytable m2
on m1.Hold=m2.Hold and m1.Source&lt;&gt;m2.Source and m1.EID is null

dbfiddle

答案6

得分: 1

以下是翻译好的部分:

尝试以下代码以获得所需的输出。
希望这对您有帮助。

创建表 t
(
EID varchar(20),
HOLD varchar(20),
[Source] varchar(40)
)

向表 t 中插入数据
Select '3232','KLME','jame.k@gmail.com'
union all select '    ','KLME','https://google.com'
union all select '    ','EEME','david.e@gmail.com'
union all select '    ','JJIN','Test@gmail.com'
union all select '7232','JJIN','https://google.com'

更新表 t
 t.EID 设置为 t1.EID
 t,
( t 中选择 EID,HOLD,其中 t.EID 不等于 '') t1
其中 t1.HOLD = t.hold
 t.EID = ''

从表 t 中选择所有数据

输出:

EID	    HOLD	Source
---------------------------
3232	KLME	jame.k@gmail.com
3232	KLME	https://google.com
    	EEME	david.e@gmail.com
7232	JJIN	Test@gmail.com
7232	JJIN	https://google.com
英文:

Try the below code to get the desired outputs.
Hope this helps.

Create table t
(
EID varchar(20),
HOLD varchar(20),
[Source] varchar(40)
)

insert into t
Select &#39;3232&#39;,&#39;KLME&#39;,&#39;jame.k@gmail.com&#39;
union all select &#39;    &#39;,&#39;KLME&#39;,&#39;https://google.com&#39;
union all select &#39;    &#39;,&#39;EEME&#39;,&#39;david.e@gmail.com&#39;
union all select &#39;    &#39;,&#39;JJIN&#39;,&#39;Test@gmail.com&#39;
union all select &#39;7232&#39;,&#39;JJIN&#39;,&#39;https://google.com&#39;

update t
set t.EID = t1.EID
FROM t,
(Select EID,HOLD from t where t.EID &lt;&gt; &#39;&#39;) t1
where t1.HOLD = t.hold
and t.EID = &#39;&#39;

Select * from t

OUTPUT:

EID	    HOLD	Source
---------------------------
3232	KLME	jame.k@gmail.com
3232	KLME	https://google.com
    	EEME	david.e@gmail.com
7232	JJIN	Test@gmail.com
7232	JJIN	https://google.com


</details>



huangapple
  • 本文由 发表于 2023年6月15日 07:18:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76478155.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定