Sql-Server

將子查詢(使用 IN)多次執行更新語句(SQL Server 2017)

  • February 6, 2020

更新語句正在更新子查詢返回的值 - 將為每一行執行子查詢嗎?

UPDATE a 
SET DM = 1
FROM TableA a 
WHERE a.ID NOT IN (SELECT DISTINCT ID FROM TableA WHERE DM = 1) 

列 ID 在表中不是唯一的,因此我們可以有多個行作為一個 ID

它是否總是將 ID 的所有行更新為 DM = 1 或有時只更新一個?

它是否總是將 ID 的所有行更新為 DM = 1 或有時只更新一個?

如果列中沒有NULL值,ID則要麼 all DM’s 用於一種類型,ID != 1因此所有ID具有相同值的 ’s 都將被更新,或者沒有。

但如前所述,根據ID列的可空性,您可以獲得令人驚訝的結果和性能影響。

更多關於NOT IN這裡NOT EXISTS

由於使用而添加了線軸和多個表訪問的範例NOT IN

在此處輸入圖像描述

編寫查詢的更簡潔的方法:

UPDATE a 
SET a.DM = 1
FROM TableA a
WHERE NOT EXISTS 
(
SELECT ID FROM TableA  b
WHERE b.DM = 1
AND b.ID = a.id );

請注意,NULL值也會更新,您必須添加額外的邏輯,例如添加AND a.id IS NOT NULL;.

產生的更清潔的加入路徑:

在此處輸入圖像描述

導致發生 0 次更新的空值範例:

CREATE TABLE dbo.TableA (id int,DM int);

INSERT INTO dbo.TableA(id,DM)

SELECT TOP 500 
ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) %200, 1
FROM MASTER..spt_values spt1
CROSS APPLY MASTER..spt_values spt2;

INSERT INTO dbo.TableA(id,DM)

SELECT TOP 500 
ROW_NUMBER() OVER(ORDER BY(SELECT NULL)) +200  , 0
FROM MASTER..spt_values spt1
CROSS APPLY MASTER..spt_values spt2;

INSERT INTO dbo.TableA(id,DM)
VALUES(NULL,1),(NULL,0);

UPDATE a 
SET DM = 1
FROM TableA a 
WHERE a.ID NOT IN (SELECT DISTINCT ID FROM TableA WHERE DM = 1) ;

–> 0 行受影響

UPDATE a 
SET a.DM = 1
FROM TableA a
WHERE NOT EXISTS 
(
SELECT ID FROM TableA  b
WHERE b.DM = 1
AND b.ID = a.id )
AND a.id IS NOT NULL; --If you do not want to update null id's

–>(受影響的 500 行)

引用自:https://dba.stackexchange.com/questions/259042