答案在一般情况下:
SELECT * FROM tableA
UNION
SELECT * FROM tableB
EXCEPT
SELECT * FROM tableA
INTERSECT
SELECT * FROM tableB;
详细的解答:
问:什么字母SQL代表什么? A.几乎不到资格作为一个语言...... ROFL但考虑到以下严重点:
CREATE TABLE MyTable
(ID INTEGER NOT NULL UNIQUE, data_col VARCHAR(10) NOT NULL);
DECLARE @MyTable TABLE
(ID INTEGER NOT NULL UNIQUE, data_col VARCHAR(10) NOT NULL);
现在的问题:
问:在语言(计算机科学)而言,是@MyTable
变量? A.嗯......
问题1:无法将表格值分配给@MyTable
例如,
-- Assignment attempt 1:
SET @MyTable = MyTable; -- COMPILE ERROR
-- Assignment attempt 2:
SET @MyTable = (VALUES (1, NULL), (2, ''), (3, 'Test')); -- COMPILE ERROR
问题2:无法比较变量,例如:
-- Comparison attempt 1:
IF (@MyTable = @MyTable) BEGIN;
PRINT 'Tables are the same.'
END; -- COMPILE ERROR
-- Comparison 2:
IF (@MyTable = (VALUES (1, NULL), (2, ''), (3, 'Test'))) BEGIN;
PRINT 'Tables are the same.'
END; -- COMPILE ERROR
...所以我们必须相信@MyTable是一个既不支持赋值又不支持比较的“变量”。
问:如果@MyTable
是一个变量,那么语言(计算机科学)术语是MyTable
? A. Constrant?值?类型?类?结构?以上都不是?
...是的,SQL确实是一种很奇怪的语言!
问:什么是关系运算符? A.在关系模型中,它是一个运算符,它将两个关系值作为参数,并返回一个关系值作为结果。
问:SQL是否支持关系运算符? A.不完全。 SQL确实有操作员会熟悉真正的关系语言(UNION
,INTERSECT
,EXCEPT
等)的用户。但是,SQL支持非关系特性,特别是空值,重复行和重复列名。因此,需要非常小心以确保这些运营商的论据和结果等同于关系。
Q如何使用SQL的'关系式'操作符来比较两个表是否相等? 一这里有一种方法:
SELECT * FROM tableA
UNION
SELECT * FROM tableB
EXCEPT
SELECT * FROM tableA
INTERSECT
SELECT * FROM tableB;
测试以证明上述(注意,以下是不所有关系值,但也证明了运营商与SQL空值逻辑工作):
例1:表是相同的(预期零行== PASS):
WITH tableA AS
(SELECT * FROM (VALUES (1, NULL),
(2, ''),
(3, 'Test')
) AS T (ID, data_col)),
tableB AS
(SELECT * FROM (VALUES (1, NULL),
(2, ''),
(3, 'Test')
) AS T (ID, data_col))
SELECT * FROM tableA
UNION
SELECT * FROM tableB
EXCEPT
SELECT * FROM tableA
INTERSECT
SELECT * FROM tableB;
实施例2:tableB的是tableB的的适当子集(期望行== FAIL):
WITH tableA AS
(SELECT * FROM (VALUES (1, NULL),
(2, ''),
(3, 'Test')
) AS T (ID, data_col)),
tableB AS
(SELECT * FROM (VALUES (1, NULL),
(2, '')
) AS T (ID, data_col))
SELECT * FROM tableA
UNION
SELECT * FROM tableB
EXCEPT
SELECT * FROM tableA
INTERSECT
SELECT * FROM tableB;
实施例3:表A是tableB的的适当子集(期望行== FAIL):
WITH tableA AS
(SELECT * FROM (VALUES (1, NULL),
(3, 'Test')
) AS T (ID, data_col)),
tableB AS
(SELECT * FROM (VALUES (1, NULL),
(2, ''),
(3, 'Test')
) AS T (ID, data_col))
SELECT * FROM tableA
UNION
SELECT * FROM tableB
EXCEPT
SELECT * FROM tableA
INTERSECT
SELECT * FROM tableB;
实施例4:表A和tableB的具有一些但不是全部共用行值(期望行== FAIL):
WITH tableA AS
(SELECT * FROM (VALUES (1, NULL),
(4, 'Lone')
) AS T (ID, data_col)),
tableB AS
(SELECT * FROM (VALUES (1, NULL),
(4, 'Sole')
) AS T (ID, data_col))
SELECT * FROM tableA
UNION
SELECT * FROM tableB
EXCEPT
SELECT * FROM tableA
INTERSECT
SELECT * FROM tableB;
实施例5:表A和tableB的具有共同(期望行)没有行值== FAIL:
WITH tableA AS
(SELECT * FROM (VALUES (5, NULL),
(6, 'Different')
) AS T (ID, data_col)),
tableB AS
(SELECT * FROM (VALUES (7, NULL),
(8, 'Not the same')
) AS T (ID, data_col))
SELECT * FROM tableA
UNION
SELECT * FROM tableB
EXCEPT
SELECT * FROM tableA
INTERSECT
SELECT * FROM tableB;
问:为什么SQL Server数据库管理员倾向于不使用此语法,并且倾向于使用FULL OUTER JOIN
?可能出于各种原因,如熟悉传统语法(例如,在SQL Server 2005中引入了EXCEPT
)。但最有可能的是,SQL DBA往往希望写出他们认为最有效的查询(贬义,过早的优化)。确实如此,SQL Server优化器不能很好地应对运营商INTERSECT
和EXCEPT
。
问:为什么更喜欢“关系式”运算符? A.因为它们不那么冗长,可以说比较容易阅读。这两个都是测试代码的好品质。
表中是否有关键列?是否有任何独特的列组合? – Laurence
使用此:http://www.red-gate.com/products/sql-development/sql-data-compare/ –
嗨劳伦斯,这两个数据集没有关键列,但所有列的组合是唯一的。 – nzsquall