2012-09-26 52 views
4

我正試圖找回所有不是父母的子女。找到並非父母的所有子女

的表看起來像這樣

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) 

但是這將返回所有行

任何人都可以告訴我,我很想念

謝謝!

回答

7

使用not in公開了一個衆所周知的SQL怪癖:

WHERE ID NOT IN (SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp]) 

要理解爲什麼,exand查詢:

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(如添Schmelter的答案),或排除null

WHERE ID NOT IN (
    SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp] WHERE ParentID IS NOT NULL) 
+0

+ 1對你的很好的解釋!謝謝 – Marc

+0

+1,這就是我想說的。很好的解釋。 –

1
SELECT * 
FROM [SMD].[dbo].[ProposalFollowUp] 
WHERE ID NOT IN (SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp] WHERE ParentID IS NOT NULL) 
+0

ParentId是父母的。所以他們可以有一個父母,但沒有孩子 – Marc

+0

@Marc看到我更新的答案。 –

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。因此,這不是父母。

+0

+1爲快速回復。謝謝 – Marc

1

爲什麼它不工作。

你是第一個查詢檢索沒有行:

SELECT * 
FROM [SMD].[dbo].[ProposalFollowUp] 
WHERE ID NOT IN (SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp]) 

因爲在ParentID那裏的謂詞NULL值變得UNKNOWN因此沒有返回值,您可以通過使用NOT EXISTS避免這種情況:

SELECT * 
FROM [SMD].[dbo].[ProposalFollowUp] 
WHERE NOT EXISTS (SELECT ParentID FROM [SMD].[dbo].[ProposalFollowUp]) 

與sQL中的所有其他謂詞不同NOT EXISTS適用於兩個值邏輯TRUEFALSE由於存在(ture)或錯誤的值只有兩種可能性,所以無法返回UNKNOWN

也有另一種解決辦法,不會讓你在你的情況,這是在尋找什麼,通過消除使用AND ParentID IS NOT NULL這些NULL值,但在你的情況就不會得到你正在尋找

結果
+0

'哪裏不存在'?不認爲這是SQL;) – Andomar

+0

我猜這是一個錯字:'WHERE ID不存在** IN **(SELECT ...' –

+1

不幸的是,'id不存在'不是SQL。子查詢中的where子句 – Andomar

0

如果只希望孩子們的ID(誰沒有父母),你也可以使用EXCEPT

SELECT ID 
FROM [SMD].[dbo].[ProposalFollowUp] 

EXCEPT 

SELECT ParentID 
FROM [SMD].[dbo].[ProposalFollowUp] ; 
0

Relace =上<>

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)