[英]Delete equal data from two tables in SQL Server
I have 2 tables with these columns: 我有两列这些表:
Table A 表A
Id | Name | Salary
1 | TEST1 | 100
2 | TEST2 | 200
3 | TEST3 | 300
Table B 表B
Id | Name | Salary
1 | TEST1 | 100
2 | TEST2 | 200
4 | TEST4 | 400
I want to delete similar data from two tables (without using joins). 我想从两个表中删除类似的数据(不使用联接)。 When I query
当我查询
SELECT *
FROM A
SELECT *
FROM B
I should get this result: 我应该得到以下结果:
Table A 表A
Id | Name | Salary
3 | TEST3 | 300
Table B 表B
Id | Name | Salary
4 | TEST4 | 400
Any help would be greatly appreciated. 任何帮助将不胜感激。 Thanks in advance.
提前致谢。
PS : I'm going to load the table with around 10 millions rows PS:我将向该表加载约1000万行
Use NOT EXISTS
使用
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)
For all the field's use EXCEPT
对于所有领域,请使用
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
To delete the records from tablea
use the below query 要从
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
Before deleting the data from tableA
insert the data into temp table to refer when deleting data from tableB
从删除数据之前
tableA
将数据插入到临时表从删除数据时,参考tableB
Use DELETE FROM
: 使用
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;
Output: 输出:
TableA:
╔════╦═══════╦════════╗
║ Id ║ Name ║ Salary ║
╠════╬═══════╬════════╣
║ 3 ║ TEST3 ║ 300 ║
╚════╩═══════╩════════╝
TableB:
╔════╦═══════╦════════╗
║ Id ║ Name ║ Salary ║
╠════╬═══════╬════════╣
║ 4 ║ TEST4 ║ 400 ║
╚════╩═══════╩════════╝
EDIT: 编辑:
To avoid coping entire table use OUTPUT
clause; 为了避免处理整个表,请使用
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);
To avoid delete problems (log growth, tempdb pressure and so on) you could process data using 100k chunk each. 为了避免删除问题(日志增长,tempdb压力等),您可以每个使用100k块来处理数据。 Add
WHILE LOOP
with 2 variables @range_start, @range_stop
and increment by 100k or any other value that suits your system. 使用2个变量
@range_start, @range_stop
添加WHILE LOOP
@range_start, @range_stop
并递增100k或其他适合您系统的值。
You better replace "delete lots of rows" to "create a new table with only those rows remaining" . 您最好将“删除许多行”替换为“仅保留那些行来创建新表” 。
Very simple if your SQL Server version supports EXCEPT
: 如果您的SQL Server版本支持
EXCEPT
则非常简单:
SELECT * INTO newA FROM a
EXCEPT
SELECT * FROM b
;
SELECT * INTO newB FROM b
EXCEPT
SELECT * FROM a
;
EXISTS
also simplifies NULL
treatment. EXISTS
还简化了NULL
处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.