views:

43

answers:

4

I have a table (TableA) where the primary key exists as a foreign key on another table (TableB). I am trying to write a SQL query (I am using SQL Server 2005) that will find all of the records in TableA where the primary key does not exist in TableB as a foreign key (we'll say joining on TableAID). I suspect it will use an outer join, but I have been struggling. Can anyone help a SQL newb out?

+4  A: 
SELECT A.*
FROM TableA AS A
LEFT JOIN TableB AS B ON (A.ID = B.TableAID)
WHERE B.TableAID IS NULL
NYSystemsAnalyst
@DaMartyr, you are correct. A `LEFT JOIN` is an OUTER JOIN. Technically `LEFT OUTER JOIN`.
Marcus Adams
This may be less efficient than the not exists approach in the other answers.
Frank
+4  A: 

You can use NOT EXISTS

SELECT columnlist
FROM TableA
WHERE NOT EXISTS(
   SELECT * FROM TableB
   WHERE TableB.column = TableA.column)
JNK
A: 
Select * from TableA 
where 
 TableA.TableAID not in (select TableB.TableAID from TableB)
Achilles
This will perform considerably worse than the not exists query suggested by others.
Tom
He didn't ask for the most performant way...:-D
Achilles
This will deliver an empty result if TableB.TableAID is null for at least one record.
Frank
I really try not to use IN if it can be avoided since it is such a slow operation, and doesn't play nice with NULL.
JNK
@Frank but how do I know that from his question??? He said the data integrity issue is the opposite of what you are saying is a concern.
Achilles
@Achilles - Yes, he did not state if there are nulls in TableB.TableAID. But he also did not state there are no nulls. And the NOT EXISTS or LEFT JOIN/IS NULL solutions deliver a correct result in both cases, and the NOT IN() solution delivers an empty result if there are nulls - which is just wrong (assuming there are IDs in TableA that have no matching keys in TableB).
Frank
+2  A: 

This is nearly natural language in SQL ("WHERE NOT EXISTS"):

SELECT A.*
FROM TableA AS A
WHERE NOT EXISTS ( SELECT 1
                   FROM TableB
                   WHERE TableA.ID = B.TableAID
                 )
Frank
+1 I was kidding :-D
Achilles