我正在尝试检索所有非父母的孩子。
表格如下所示
ID | ParentID
---------------
1 NULL
2 1
3 NULL
4 2
起初我试过
SELECT *
FROM [SMD].[dbo].[ProposalFollowUp]
WHERE ID NOT IN (SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp])
但它不返回任何行。 我想选择不在parentID中的所有行。我不明白为什么它不起作用。
然后我尝试了这个
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)
但这会返回所有行
任何人都可以告诉我我缺少的东西
谢谢!
答案 0 :(得分:7)
使用not in
公开了一个众所周知的SQL怪癖:
WHERE ID NOT IN (SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp])
要理解原因,请查询:
WHERE ID NOT IN (null, 1, null, 2)
这转化为:
where id <> null and id <> 1 and id <> null and id <> 2
诀窍是id <> null
永远不会成真。在SQL的three-valued logic中,它的计算结果为unknown
。这意味着你的where子句永远不会批准任何一行。
要解决此问题,请使用exists
(如Tim Schmelter的回答),或从子查询中排除null
:
WHERE ID NOT IN (
SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp] WHERE ParentID IS NOT NULL)
答案 1 :(得分:3)
您可以使用NOT EXISTS
:
SELECT ID, ParentID
FROM [SMD].[dbo].[ProposalFollowUp] t1
WHERE NOT EXISTS
(
SELECT 1 FROM [SMD].[dbo].[ProposalFollowUp] t2
WHERE t2.ParentID = t1.ID
)
这仅返回ID
不是另一行ParentID
的行。因此,这不是父母。
答案 2 :(得分:1)
SELECT *
FROM [SMD].[dbo].[ProposalFollowUp]
WHERE ID NOT IN (SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp] WHERE ParentID IS NOT NULL)
答案 3 :(得分:1)
为什么它不起作用。
您正在检索第一个查询中没有行:
SELECT *
FROM [SMD].[dbo].[ProposalFollowUp]
WHERE ID NOT IN (SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp])
由于谓词NULL
中的ParentID
值变为UNKNOWN
,因此不返回任何内容,您可以使用NOT EXISTS
来避免这种情况:
SELECT *
FROM [SMD].[dbo].[ProposalFollowUp]
WHERE NOT EXISTS (SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp])
与sQL NOT EXISTS
中的所有其他谓词不同,两个值逻辑TRUE
和FALSE
的工作原理是,只有两个值存在(ture)或false的可能性存在无法返回UNKNOWN
。
还有另一种解决方法,在您的情况下无法获得您想要的内容,即使用NULL
消除这些AND ParentID IS NOT NULL
值,但在您的情况下不会得到您您正在寻找的结果
答案 4 :(得分:0)
如果您只想要孩子的ID(不是父母),您也可以使用EXCEPT
:
SELECT ID
FROM [SMD].[dbo].[ProposalFollowUp]
EXCEPT
SELECT ParentID
FROM [SMD].[dbo].[ProposalFollowUp] ;
答案 5 :(得分:0)
Relace = on&lt;&gt;
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)