sql select puzzle:当父进程被过滤掉时删除子进程

时间:2011-02-24 23:11:49

标签: sql select parent-child

我基本上有一张桌子:

name         has_children      parent_id    row_id values0.....valuesn
parent       1                 1            1
children     0                 1            2
children     0                 1            3
parent       0                 4            4
parent       1                 5            5
children     0                 5            6
children     0                 5            7

子项的值可以与父项的值不同。 我想要一些选择/连接,它将过滤值列上的表(即> 10)并返回父项(即使过滤器为false),如果其中一个子项对过滤器为真。

acceptable return:
parent=true    all children=false, return just parent
parent=false   >=1 children=true, return parent and all non-filtered child

我确信之前已经考虑过这个问题,但我并不知道如何用问题来寻找解决方案。

2 个答案:

答案 0 :(得分:2)

符合ANSI标准。每个特定的DBMS可能具有更快的实现

select *
from tbl
where id in-- PARENTS of CHILDREN that match
(   select parent_id from tbl
    where values0 > 10 and has_children = 0)
or id in   -- ONE CHILD ONLY
(   select MIN(id) from tbl
    where values0 > 10 and has_children = 0
    group by parent_id)
or id in   -- PARENTS
(   select id from tbl
    where values0 > 10 and has_children = 1)

最好写成一个JOIN

select t.*
from 
(   select parent_id as ID from tbl
    where values0 > 10 and has_children = 0
    UNION
    select MIN(id) from tbl
    where values0 > 10 and has_children = 0
    group by parent_id
    UNION
    select id from tbl
    where values0 > 10 and has_children = 1) X
join tbl t on X.ID = t.ID

答案 1 :(得分:0)

最简单的方法是将它们作为两个单独的查询来处理它们之间的UNION。

  1. 选择条件下所有子项均为false的父级。
  2. 选择父级和某个孩子(MAX或MIN可能最简单)。