簡體   English   中英

從SQL Server中的兩個表中刪除相等的數據

[英]Delete equal data from two tables in SQL Server

我有兩列這些表:

表A

Id | Name  | Salary  
1  | TEST1 | 100  
2  | TEST2 | 200  
3  | TEST3 | 300

表B

Id | Name  | Salary  
1  | TEST1 | 100  
2  | TEST2 | 200  
4  | TEST4 | 400

我想從兩個表中刪除類似的數據(不使用聯接)。 當我查詢

SELECT * 
FROM A 

SELECT * 
FROM B

我應該得到以下結果:

表A

Id | Name  | Salary   
3  | TEST3 | 300

表B

Id | Name  | Salary   
4  | TEST4 | 400

任何幫助將不勝感激。 提前致謝。

PS:我將向該表加載約1000萬行

使用NOT EXISTS

SELECT * 
FROM   a 
WHERE  NOT EXISTS (SELECT 1 
                   FROM   b 
                   WHERE  a.id = b.id) 

SELECT * 
FROM   b 
WHERE  NOT EXISTS (SELECT 1 
                   FROM   a 
                   WHERE  a.id = b.id) 

對於所有領域,請使用EXCEPT

SELECT Id, Name, Salary FROM A
EXCEPT
SELECT Id, Name, Salary FROM B

SELECT Id, Name, Salary FROM B
EXCEPT
SELECT Id, Name, Salary FROM A

要從tablea刪除記錄,請使用以下查詢

WITH cte 
     AS (SELECT * 
         FROM   tablea a 
         WHERE  EXISTS (SELECT 1 
                        FROM   tableb b 
                        WHERE  a.id = b.id 
                               AND a.NAME = b.NAME 
                               AND a.salary = b.salary)) 
DELETE FROM cte 

SELECT * 
FROM   tablea 

從刪除數據之前tableA將數據插入到臨時表從刪除數據時,參考tableB

使用DELETE FROM

SELECT *
INTO #temp
FROM TableA;    -- to get the same data to compare with second DELETE

DELETE t
FROM TableA t
WHERE EXISTS(SELECT Id,Name,Salary
             FROM TableB
             INTERSECT
             SELECT t.ID, t.Name, t.Salary);

DELETE t
FROM TableB t
WHERE EXISTS(SELECT Id,Name,Salary
             FROM #temp
             INTERSECT
             SELECT t.ID, t.Name, t.Salary);  


SELECT * FROM TableA;
SELECT * FROM TableB;

LiveDemo

輸出:

 TableA:
╔════╦═══════╦════════╗
║ Id ║ Name  ║ Salary ║
╠════╬═══════╬════════╣
║  3 ║ TEST3 ║    300 ║
╚════╩═══════╩════════╝


TableB:
╔════╦═══════╦════════╗
║ Id ║ Name  ║ Salary ║
╠════╬═══════╬════════╣
║  4 ║ TEST4 ║    400 ║
╚════╩═══════╩════════╝

編輯:

為了避免處理整個表,請使用OUTPUT子句;

CREATE TABLE #temp(ID INT, NAME VARCHAR(100), Salaray INT);

DELETE t
OUTPUT deleted.Id, deleted.Name, deleted.Salary
INTO #temp
FROM TableA t
WHERE EXISTS(SELECT Id,Name,Salary
             FROM TableB
             INTERSECT
             SELECT t.ID, t.Name, t.Salary);

DELETE t
FROM TableB t
WHERE EXISTS(SELECT Id,Name,Salary 
             FROM (SELECT Id,Name,Salary FROM TableA
                   UNION ALL
                   SELECT Id,Name,Salary FROM #temp) AS sub
             INTERSECT
             SELECT t.ID, t.Name, t.Salary); 

LiveDemo2

為了避免刪除問題(日志增長,tempdb壓力等),您可以每個使用100k塊來處理數據。 使用2個變量@range_start, @range_stop添加WHILE LOOP @range_start, @range_stop並遞增100k或其他適合您系統的值。

您最好將“刪除許多行”替換為“僅保留那些行創建新表”

如果您的SQL Server版本支持EXCEPT則非常簡單:

SELECT * INTO newA FROM a
EXCEPT
SELECT * FROM b
;

SELECT * INTO newB FROM b
EXCEPT
SELECT * FROM a
;

小提琴

EXISTS還簡化了NULL處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM