Question

I want to retrieve all records from one table when there are no matches in the second table.

So it is kind of the opposite of an inner join.

Was it helpful?

Solution

You need a LEFT JOIN WHERE IS NULL query (aka outer join):

SELECT table1.*
FROM table1
LEFT OUTER JOIN table2 
   ON table1.id = table2.id
WHERE table2.id IS NULL

Or a NOT IN:

SELECT *
FROM table1
WHERE id NOT IN (SELECT id FROM table2)

OTHER TIPS

You have three options:

  1. Correlated sub-query.

    SELECT * FROM TableA WHERE NOT EXISTS (SELECT * FROM TableB WHERE TableB.ID = TableA.ID)

  2. Non-correlated sub-query.

    SELECT * FROM TableA WHERE ID NOT IN (SELECT ID FROM TableB)

  3. OUTER JOIN with NULL elimination.

    SELECT * FROM TableA LEFT [OUTER] JOIN TableB ON TableA.ID = TableB.ID WHERE TableB.ItsPrimaryKey IS NOT NULL

In the last example some DBMSes require the word OUTER, some permit it, and some do not allow it at all.

Depending on the DBMS, the various options might produce different execution plans and different performance. Select the one with good performance and that best expresses your intent.

It's an outer join:

SELECT *
  FROM tableA AS a
  LEFT JOIN tableB AS b USING(x)

Say you have:

tableA:

a | x
-----
1 | 1
3 | 3

table B:

b | x
-------
1 | 'a'
2 | 'b'

then the query above will give you

a |  b   | x
------------
1 |  'a' | 1
3 | NULL | 3

if you want

a    |  b   | x
----------------
1    | 'a'  | 1
NULL | 'b'  | 2
3    | NULL | 3

you have to use FULL OUTER JOIN instead of LEFT JOIN.

EDIT: As Larry Lustig told me (and I think is correct after rereading the question) the OP does not want any rows from B. So the query should be:

SELECT a.*
  FROM tableA AS a
  LEFT JOIN tableB AS b USING(x)
 WHERE b.x IS NULL

that will yield

 a | x 
-------
 3 | 3

The "opposite" of inner join is called outer join.

Outer join. Technically possibly FULL OUTER JOIN ;)

Adding to the Solution of Johannes Weiß the solution to your other question about finding objects in table a without objects in table b:

SELECT *
FROM tableA AS a
LEFT JOIN tableB AS b
USING(x)
WHERE b.foo IS NULL

You are looking for LEFT JOIN or FULL OUTER JOIN Not all DBMS support FULL though.

Simulation of it is possible with UNION, example in MySQL:

SELECT * FROM t1
LEFT JOIN t2 ON t1.id = t2.id
UNION
SELECT * FROM t1
RIGHT JOIN t2 ON t1.id = t2.id

I believe you are looking for FULL OUTER JOIN (works with Oracle 9i+).

EDIT: didn't read your question well... LEFT JOIN if you only want NULL values for the second table

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top