我曾经使用'EXCEPT'从应该具有相同数据但被告知不再使用它的2个表中查找丢失的数据。我找到了一个解决方案,但是我不完全确定它是如何工作的。有人可以给我解释一下还是帮我解决另一个问题?
这是我查询的基本示例:
SELECT MIN(C.TABLE_NAME) as TABLE_NAME,columnid,column
FROM
(
SELECT DISTINCT 'Source' as TABLE_NAME,columnid,column
FROM table1
UNION ALL
SELECT DISTINCT 'Output' as TABLE_NAME,columnid,column
FROM table2
) AS C
GROUP BY columnid,column
HAVING COUNT(*) = 1;
如果数据匹配,则输出结果不应显示任何行。上面的代码按预期在我在一个表上进行了测试,在该表上我知道数据是匹配的而不匹配的。我只是不确定它是如何工作的。很抱歉这个简单的问题。我是新来的。
编辑: 如果有帮助,我迅速制作了一些示例数据。
WITH salesman AS
(
SELECT 5005 AS id, 'Pit Alex' AS [name]
UNION ALL
SELECT 5006 AS id, 'Mc Lyon' AS [name]
UNION ALL
SELECT 5011 AS id, 'Lauson Hen' AS [name]
UNION ALL
SELECT 5007 AS id, 'Paul Adam' AS [name]
) ,
salesmancopy AS
(
SELECT 5005 AS id, 'Pit Alex' AS [name]
UNION ALL
SELECT 5006 AS id, 'Mc Lyon' AS [name]
UNION ALL
SELECT 5010 AS id, 'Lauson Hen' AS [name]
)
SELECT MIN(C.TABLE_NAME) as TABLE_NAME,id,[name]
FROM
(
SELECT DISTINCT 'original' as TABLE_NAME,id,[name]
FROM salesman
UNION ALL
SELECT DISTINCT 'copy' as TABLE_NAME,id,[name]
FROM salesmancopy
) AS C
GROUP BY id,[name]
HAVING COUNT(*) = 1;
答案 0 :(得分:1)
如果您希望table1
中的行不在table2
中,那么仅当table2
不包含某些唯一行时,您的解决方案才有效。换句话说,table2
中的行必须存在于table1
中。另一种解决方案是使用NOT EXISTS
select *
from table1 t1
where not exists (
select 1
from table2 t2
where t1.columnid = t2.columnid and
t1.column = t2.column
)
Here,您可以看到针对此问题的不同方法的比较,其中NOT EXISTS
解决方案优于LEFT JOIN + IS NULL
解决方案。
答案 1 :(得分:1)
除了是确定一侧是否存在的最快方法。
但是,如果您想一次检查两个表,则可以使用FULL OUTER JOIN
IF OBJECT_ID('tempdb..#t1') IS NOT NULL
DROP TABLE #t1;
IF OBJECT_ID('tempdb..#t2') IS NOT NULL
DROP TABLE #t2;
SELECT *
INTO #t1
FROM (SELECT 1 AS num UNION SELECT 2 AS num UNION SELECT 3 AS num) d;
SELECT *
INTO #t2
FROM (SELECT 1 AS num UNION SELECT 2 AS num UNION SELECT 5 AS num) d;
SELECT *
FROM #t1
FULL OUTER JOIN #t2
ON #t2.num = #t1.num
WHERE #t1.num IS NULL
OR #t2.num IS NULL;
输出:
答案 2 :(得分:-1)
要解决RadimBača提到的问题,即,如果您需要弄清两个表之间的差异,则当table2中不存在行但table1中存在行时,可以选择以下选项。
1.Create two column to indicate if the record is from original or copy
2.group by the columns you wish to compare.
3.use the clause having count(orig)<> count(copy)
使用与以前相同的查询,但进行小的更改,
WITH salesman AS
(
SELECT 5005 AS id, 'Pit Alex' AS [name]
UNION ALL
SELECT 5006 AS id, 'Mc Lyon' AS [name]
UNION ALL
SELECT 5011 AS id, 'Lauson Hen' AS [name]
UNION ALL
SELECT 5007 AS id, 'Paul Adam' AS [name]
) ,
salesmancopy AS
(
SELECT 5005 AS id, 'Pit Alex' AS [name]
UNION ALL
SELECT 5006 AS id, 'Mc Lyon' AS [name]
UNION ALL
SELECT 5010 AS id, 'Lauson Hen' AS [name]
)
SELECT c.id
,c.name
,count(orig) as present_in_orig
,count(copy) as present_in_copy
FROM
(
SELECT 'original' as orig
,null as copy
,id
,[name]
FROM salesman
UNION ALL
SELECT null as orig
,'copy' as copy
,id
,[name]
FROM salesmancopy
) AS C
GROUP BY id
,[name]
HAVING COUNT(copy)<> count(orig)
order by 1,2
请参见Stew的以下链接,该链接非常详细地介绍了此方法。
https://stewashton.wordpress.com/2014/02/04/compare-and-sync-tables-tom-kyte-and-group-by/