I'm trying to retrieve all children who are not parent.
The table looks like this
ID | ParentID
---------------
1 NULL
2 1
3 NULL
4 2
At first I tried
SELECT *
FROM [SMD].[dbo].[ProposalFollowUp]
WHERE ID NOT IN (SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp])
but it returns no row. I wanted to select all rows that are not in parentID. I don't understand why it's not working.
Then I tried this
SELECT *
FROM [SMD].[dbo].[ProposalFollowUp] AS a
WHERE a.ID NOT IN
(SELECT b.ID FROM [SMD].[dbo].[ProposalFollowUp] as b WHERE b.ParentID = a.ID)
but this returns all rows
Anyone can tell me what I'm missing
Thank you!
Using not in
exposes a well-known SQL quirk:
WHERE ID NOT IN (SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp])
To understand why, exand the query:
WHERE ID NOT IN (null, 1, null, 2)
And that translates to:
where id <> null and id <> 1 and id <> null and id <> 2
The trick is that id <> null
is never true. In SQL's three-valued logic, it evaluates to unknown
. And that means your where clause never approves any row.
To solve this, use exists
(like Tim Schmelter's answer), or exclude null
from the subquery:
WHERE ID NOT IN (
SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp] WHERE ParentID IS NOT NULL)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With