I have two tables with identical fields that share many rows. I'd like to list all the rows in one table that cannot be matched in the other. Specifically, these two tables are two different versions of an experiment where the results differ slightly. An example is something like this:
|TableA|
--------
horse
cat
cow
table
|TableB|
--------
horse
cat
chair
I'd like to be able to see that TableA
is missing chair
from TableB
and possibly in a different query that TableB
is missing cow
and table
are missing from TableA
.
My thought was to do some sort of outer join on all fields, then sort out the rows with nulls in them, but this seems heavy handed. Is this the way to go or is there are mo开发者_如何学编程re elegant/efficient approach?
Using NOT IN:
SELECT a.column
FROM TABLE_A a
WHERE a.column NOT IN (SELECT b.column
FROM TABLE_B b)
Using NOT EXISTS:
This is a good one if you need to compare more than one column...
SELECT a.column
FROM TABLE_A a
WHERE NOT EXISTS(SELECT NULL
FROM TABLE_B b
WHERE b.column = a.column)
Using LEFT JOIN/IS NULL:
SELECT a.column
FROM TABLE_A a
LEFT JOIN TABLE_B b ON b.column = a.column
WHERE b.column IS NULL
Because of the table aliases, you could swap the table names without changing the rest of the query to see the opposite--rows from TABLE_B that aren't in TABLE_A.
be conscious when you are using IN clause for NULLABLE columns
If you want a single listing of all the rows that are in the left table and not the right one and all the rows that are in the right table and not the left table:
CREATE TABLE test1 (
idOne int identity primary key
,nameOne nvarchar (3)
)
CREATE TABLE test2 (
idTwo int identity primary key
,nameTwo nvarchar (3)
)
INSERT INTO test1 (nameOne) VALUES
('one'),
('two'),
('thr')
INSERT INTO test2 (nameTwo) VALUES
('one'),
('tre')
SELECT 'test2 row', idOne, nameOne, idTwo, nameTwo FROM test1 t1
RIGHT JOIN test2 t2 ON
t1.idOne = t2.idTwo and
t1.nameOne = t2.nameTwo
WHERE idONE is NULL
OR idTwo is NULL
UNION ALL
SELECT 'test1 row', idOne, nameOne, idTwo, nameTwo FROM test1 t1
LEFT JOIN test2 t2 ON
t1.idOne = t2.idTwo and
t1.nameOne = t2.nameTwo
WHERE idOne is NULL
OR idTwo is NULL
精彩评论