2010-07-26 83 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