2010-07-26 74 views
3

疲倦讓我無法找到這樣的產品......假設你有下列表格:SELECT COUNT(*)或零個

家長

  • PARENT_ID(LONG)

孩子

  • CHILD_ID(LONG)
  • PARENT_ID(LONG,FK)
  • HAS_GRADUATED(布爾)

我想如果父查詢返回以下(1,在甲骨文的情況下)至少有一個孩子已經畢業了,(0,在情況下,如果甲骨文)如果家長不具有已畢業,或根本沒有孩子一個孩子:

PARENT_ID ................ HAS_CHILDREN_WHO_GRADUATED

5 .......................... ....... 1

3 ................................. 1

6 ................................. 0

2 ......... ........................ 0

在上面,parent_id = 5的父代可能有> = 1個畢業的孩子。父母與parent_id = 3一樣。 parent_id = 6的父母根本沒有孩子,或者有孩子,但沒有一個畢業。

對此的查詢會是什麼樣子?

+1

我猜'Child'表中還有一個外鍵'PARENT_ID'? – pascal 2010-07-26 17:34:51

+0

是的,我在編寫評論時已經在編輯:-) – 2010-07-27 07:17:49

回答

0

首先,我不認爲您可以使用LONG列,因爲LONG值不能用於WHERE的條件。請注意,從10g開始,這是真的,因爲這就是我使用的。

第二我假設你的意思是你的子表應該有一個名爲PARENT_ID的列,否則就沒有辦法鏈接這兩個表。鑑於此,這個查詢應該工作:

SELECT PARENT_ID, COUNT(1) FROM Child WHERE HAS_GRADUATED = 1 GROUP BY PARENT_ID 
+1

這不會列出沒有孩子的父母。 – pascal 2010-07-26 17:39:30

+0

你說得對,我的錯誤會解決。 – Dan 2010-07-26 17:50:42

2

這會給你你所期望的嗎?

SELECT 
    P.Parent_Id, 
    CASE WHEN (SUM (CASE WHEN Has_Graduated = 1 then 1 else 0 END)) = 0 THEN 0 ELSE 1 as HAS_CHILDREN_WHO_GRADUATED 
FROM Parent P 
    LEFT JOIN Child C 
     ON P.Parent_Id = C.Parent_Id 
GROUP BY P.Parent_Id 
+0

難道這實際上不計算有多少孩子爲那個家長畢業?他特別要求1或0. – WillfulWizard 2010-07-26 17:43:11

+0

要比指出錯誤更有用,我們能否做出這樣的改變:(1 <= Count(CASE WHEN Has_Graduated = 1 then 1 else 0))? – WillfulWizard 2010-07-26 17:44:36

+1

答案已更正。 – 2010-07-26 18:00:41

7

用途:

SELECT DISTINCT 
      p.parent_id, 
      CASE WHEN c.parent_id IS NULL THEN 0 ELSE 1 END 
    FROM PARENT p 
LEFT JOIN CHILD c ON c.parent_id = p.parent_id 
       AND c.has_graduated = 1 

你必須使用一個外連接才能看到沒有在子表支持記錄父值。

+0

DISTINCT應該比一組執行更好。 – 2010-07-26 17:47:33

+0

@Philip Kelley:在Oracle上 - 他們執行相同的操作。我不得不挖掘AskTom的文章,因爲我認爲你和我的老闆一樣不知道=) – 2010-07-26 17:48:38

+0

感謝您的答案(+1)。其實,我認爲這是行不通的。如果一個父母有一個孩子已經被分級,而另一個孩子沒有畢業,最終結果集中會有兩行。其中一個帶有parent_id和1,另一個帶有parent_id和0. – 2010-07-27 08:09:50

0

這裏的查詢的形式,雖然用於Oracle的語法可能會關閉:

SELECT 
    Parent.PARENT_ID 
    ,case count(Child.PARENT_ID) when 0 then 0 else 1 end HAS_CHILDREN_WHO_GRADUATED 
from Parent 
    left outer join Child 
    on Child.PARENT_ID = Parent.PARENT_ID 
where Child.HAS_GRADUATED = 1 
group by Parent.PARENT_ID 

所期望這將列出所有父項目一次,HAS_CHILDREN_WHO_GRADUATED 設置爲1或0套。

(編輯補充where子句)

2

很可能是OMG小馬的解決方案將有更好的表現(這就是爲什麼他得到了我的+1),但這又一個解決問題的辦法。

Select Parent_Id 
    , Case 
     When Exists(Select 1 
        From Child 
        Where Child.Parent_Id = Parent.Parent_Id 
         And Child.Has_Graduated = 1) Then 1 
     Else 0 
     End 
From Parent 
+0

+1 - 你的變體作品(@OMG小馬變種返回錯誤的結果)。性能是值得懷疑的,在某些變體中你的變體工作得更快 – ThinkJet 2010-07-30 15:08:32

+0

糟糕...在@OMG小馬隊的答案中鬆動「c.has_graduated = 1」。抱歉。它也可以工作。 – ThinkJet 2010-07-30 15:17:00