views:

98

answers:

8
+2  Q: 

SQL join problem

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.

+1  A: 

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
Johannes Weiß
This is not correct. The OP does not want any rows with B values.
Larry Lustig
you're right. Thanks!
Johannes Weiß
A: 

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

Thomas Padron-McCarthy
OUTER and INNER JOINs are not opposites. An OUTER JOIN is a superset of an INNER JOIN.
Larry Lustig
A: 

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

guigui42
A: 

Outer join. Technically possibly FULL OUTER JOIN ;)

TomTom
+4  A: 

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)
froadie
To be clear, the NULL aspect of this JOIN is not part of the definition of an OUTER JOIN.
Larry Lustig
A: 

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
dbemerlin
A: 

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
douwe
No, the user is not looking for a FULL OUTER JOIN. That would return matching and non-matching row from both tables. Nor a LEFT OUTER JOIN which would return all rows from A including the undesired rows with matches.
Larry Lustig
+1  A: 

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.

Larry Lustig