CREATE TABLE union_tab_1 ( id INT, val VARCHAR(10) );
CREATE TABLE union_tab_2 ( id INT, val VARCHAR(10) );
INSERT INTO union_tab_1 VALUES(1, 'A'); INSERT INTO union_tab_1 VALUES(2, 'B'); INSERT INTO union_tab_1 VALUES(3, 'C');
INSERT INTO union_tab_2 VALUES(1, 'A'); INSERT INTO union_tab_2 VALUES(1, 'A'); INSERT INTO union_tab_2 VALUES(2, 'B'); INSERT INTO union_tab_2 VALUES(4, 'D');
MINUS / EXCEPT– 返回第一个表中有、第二个表中没有的数据
Oracle
SQL> SELECT * FROM union_tab_1 2 MINUS 3 SELECT * FROM union_tab_2;
ID VAL ---------- -------------------- 3 C
SQL> SELECT * FROM union_tab_2 2 MINUS 3 SELECT * FROM union_tab_1;
ID VAL ---------- -------------------- 4 D
SQL Server
1> SELECT * FROM union_tab_1 2> EXCEPT 3> SELECT * FROM union_tab_2; 4> go id val ----------- ---------- 3 C
(1 行受影响)
1> SELECT * FROM union_tab_2 2> EXCEPT 3> SELECT * FROM union_tab_1; 4> go id val ----------- ---------- 4 D
(1 行受影响)
通过 SET SHOWPLAN_TEXT ON 查看 查询计划.
我这里的测试表记录数量很小, 还没有索引, 因此没有参考价值.
1> SET SHOWPLAN_TEXT ON 2> go 1> SELECT * FROM union_tab_1 2> WHERE 3> id NOT IN 4> (SELECT id FROM union_tab_2) 5> go StmtText
-------------------------------------------------------------------------------- - SELECT * FROM union_tab_1 WHERE id NOT IN (SELECT id FROM union_tab_2)
(1 行受影响) StmtText
-------------------------------------------------------------------------------- -------------------------------------------------------------------------------- -------------------------------------- |--Nested Loops(Left Anti Semi Join, WHERE:([Test].[dbo].[union_tab_1].[id] IS NULL OR [Test].[dbo].[union_tab_2].[id] IS NULL OR [Test].[dbo].[union_tab_1].[ id]=[Test].[dbo].[union_tab_2].[id])) |--Table Scan(OBJECT:([Test].[dbo].[union_tab_1]))