选择满足多个子句的ID

时间:2012-02-07 09:26:31

标签: mysql sql select

很难正确输入,但我正在使用MySQL,我需要选择一个id,让我们称之为parent_id,它必须满足多行中的child_id值。

例如:

   +-----------+----------+
   | parent_id | child_id |
   +-----------+----------+
   |     1     |    10    |
   +-----------+----------+
   |     2     |    11    |
   +-----------+----------+
   |     2     |    12    |
   +-----------+----------+
   |     3     |    13    |
   +-----------+----------+
   |     4     |    11    |
   +-----------+----------+
   |     5     |    12    |
   +-----------+----------+

现在,如果我传递child_id参数11和12,我必须返回parent_id 2,但如果我传递10和11,我必须得到任何回报。另外,如果我超过11,我必须得到4.如果我通过13,我必须得到3回。

我该如何解决这个问题?我尝试计算parent_id和使用HAVING子句,也使用GROUP BY子句,但我尝试的任何内容都不符合我的所有要求。

修改

示例小提琴:http://sqlfiddle.com/#!2/abbc4/5

EDIT2:

预期结果:

通过参数:11,12 收到的结果:2

传递参数:11 收到的结果:4

传递参数:13 收到的结果:3

通过参数:12,13 收到的结果为NULL

EDIT3:

更新了规范。另见:http://sqlfiddle.com/#!2/2f750/1

3 个答案:

答案 0 :(得分:2)

以下声明可以满足您的需求。虽然我对它的表现不太确定......

select t.parent_id, t.cnt from
(
    select parent_id, count(*) cnt
    from t 
    WHERE child_id IN (12, 11)
    GROUP BY parent_id
) t
inner join
(
    select parent_id, count(*) cnt
    from t group by parent_id
) s
on t.parent_id = s.parent_id
and t.cnt = s.cnt -- Check that the parent has exactly as many children as
                  -- passed in - and not more. Prevents matching if only part
                  -- of the children of a parent were specified.
and t.cnt = 2 -- Check that all passed in children produced a match on the same
              -- parent. Prevents matching of parents that match only a subset
              -- of the specified children

2替换为IN列表中指定子项的数量。

答案 1 :(得分:1)

您也可以使用这个更紧凑的版本

select case
         when min(t.parent_id) = max(t.parent_id) -- parent_ids are the same?
              -- and all children share the same parent?
              and count(t.parent_id) = (
                          select count(parents.parent_id)
                            from t parents
                           where parents.parent_id in
                              (select parent_id
                                 from t 
                                where child_id in (11, 12) -- <= change here
                               )) 
         then t.parent_id
         else null
       end as parent_id
  from t 
 where child_id in (11, 12); -- <= and here

我已对此进行了测试,适用于所有用例

您可以在这里测试http://sqlfiddle.com/#!2/abbc4/183

答案 2 :(得分:0)

你必须有两个变量才能发挥作用。第一个是逗号分隔的child_ids列表(child_list),第二个是您要搜索的子项数(child_list中的子项数)(child_count)。

SELECT parent_id,COUNT(*) 
FROM table 
WHERE child_id IN (<child_list>) 
GROUP BY parent_id
HAVING COUNT(*)=<child_count>

这应该会给你想要的结果。