通过查看第三个来查找两个表的连接方式

时间:2015-12-23 11:46:35

标签: sql oracle having

我有几张桌子:

boxes Table         ToysTable       Kitchen Table
boxId | ID          Name  | ID      Type   |  ID
-------------      --------------   -----------
1   | TOY1        Ball    | TOY1     Fork  | KIT1
1   | TOY2        Car     | TOY2     Knife | KIT2
1   | KIT1        Puzzle  | TOY3     Spoon | KIT3
2   | KIT2

我想找到包含我的东西的盒子。 所以,如果我问: 什么盒子包含叉子和我的汽车玩具。 我希望获得该框的ID,在本例中为1。

我该怎么做?

Sqlfiddle:http://sqlfiddle.com/#!4/11b0a/3/0

编辑: 更新了厨房的列名称以进行输入。

EDIT2: 最终解决方案变得像这样(感谢Gordon):

select b.boxid
from boxes b left join
     (select id, 'toy' type
      from toys t
      where t.name in ('Car', 'Fork')
      union all
      select id, 'kitchen' type
      from kitchen k
      where k.name in ('Car', 'Fork')
     ) tk
     on b.id = tk.id
group by b.boxid
having count(distinct tk.type) = 2;

1 个答案:

答案 0 :(得分:2)

这有点棘手,因为id可能是任何一个表。一个解决方案是group byunion all。这是一种通用方法,假设两个参考表中的ID具有不同的值:

select b.boxid
from boxes b left join
     (select id, name 
      from toys t
      union all
      select id, name
      from kitchen k
     ) tk
     on b.id = tk.id
group by b.boxid
having sum(case when tk.name = 'Car' then 1 else 0 end) > 0 and
       sum(case when tk.name = 'Fork' then 1 else 0 end) > 0;

注意:在MySQL中,我会将此查询编写为:

select b.boxid
from boxes b left join
     (select id, name 
      from toys t
      where t.name in ('Car', 'Fork')
      union all
      select id, name
      from kitchen k
      where k.name in ('Car', 'Fork')
     ) tk
     on b.id = tk.id
group by b.boxid
having count(distinct name) = 2;

实际上,您可以用任何SQL方言以这种方式编写它。