答案在一般情況下:
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