Reputation: 24572
I have these SQL Statements:
SELECT COUNT(*) FROM Phrase -- Returns 660 rows
SELECT COUNT(*) FROM Score -- Returns 660 rows
SELECT count(*) -- Returns 660 rows
FROM Score AS S
JOIN Phrase AS P ON S.PhraseId = P.PhraseId
SELECT count(*) -- Returns 658 rows
FROM Score AS S
JOIN Phrase AS P ON S.PhraseId = P.PhraseId
JOIN Category AS C ON P.CategoryId = C.Id
I am trying to work out what went wrong in the database and would appreciate some advice on how I could find the phraseId of the records where a phrase has a categoryId that's not in the table Category
Upvotes: 0
Views: 48
Reputation: 35333
Use an outer join:
Return all records from score and phrase that match. Include rows from Category that match. Then exclude all of those that had a match on category, leaving you the 2 records from score/phrase that didn't match a category.
SELECT *
FROM Score AS S
JOIN Phrase AS P ON S.PhraseId = P.PhraseId
LEFT JOIN Category AS C ON P.CategoryId = C.Id
WHERE C.ID is null
Not as efficient as not exists/not in but gives you more flexibility on the columns returned.
Upvotes: 1
Reputation: 54
use can use nested subquery to get this
select count(*)
from score as S
where phraseId in
(select phraseId
from Phrase
where phaseId not in (select phraseId from category);
Upvotes: 1
Reputation: 1298
I guess you have 2 Phrase records with CategoryId = NULL, assuming there is a referential integrity constraint between Phrase and Category.
Anyway, this should list these 2 Phrase records:
SELECT * FROM Phrase WHERE CategoryId NOT IN (SELECT Id FROM Category)
Upvotes: 1
Reputation: 10701
Use NOT EXISTS
to find such ids in the Phrase
table.
SELECT * FROM Phrase AS P
WHERE NOT EXISTS (SELECT 1 FROM Category WHERE P.CategoryId = C.Id)
Another solution is to use NOT IN
however you have to be more careful about possible NULLs
SELECT * FROM Phrase AS P
WHERE P.CategoryId NOT IN(SELECT C.Id FROM Category WHERE C.Id IS NOT NULL)
Upvotes: 2