MySQL多个JOIN查询

时间:2013-01-31 15:11:59

标签: mysql

我有3张桌子:

表A:

  • id int
  • value varchar

表B:

  • id int
  • a_id default null

表C:

  • id int
  • a_id not null

我需要按A.value组合B行和C行的数量:

+---------+----------------------+----------------------+
| A.value | COUNT(DISTINCT B.id) | COUNT(DISTINCT C.id) |
+---------+----------------------+----------------------+
| NULL    | 100                  | 0                    |
| 1       | 543                  | 324                  |
...

问题是B表有一个可以为空的外键,而C.a_id不能为空。 因此,经过一小时的尝试,我无法得到正确的查询。 C.a_id正在失败或B.a_id。

获得它的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

因为值非常大,所以在子查询中进行计算可能会更好:

select a.name, Distinct_B, Distinct_C
from (select distinct a.name from TableA a) a left outer join
     (select a.value, count(distinct b.id) as Distinct_B
      from TableA a join
           TableB b
           on a.id = b.a_id
      group by a.value
     ) b
     on a.value = b.value left outer join
     (select a.value, count(distinct c.id) as distinct_C
      from TableA a join
           TableC c
           on a.id = c.a_id
    ) c
    on a.value = c.value

这看起来更复杂,但在每个a.value中不需要部分笛卡尔积。此外,如果没有允许多个a.values,它可以简化。

如果要通过为它们分配NULL a.value来保留所有具有“NULL”a_id的B值,则改为使用此子查询:

select a.value, sum(Distinct_B), sum(Distinct_C)
from ((select distinct a.name, 0 as Distinct_B, 0 as Distinct_C
       from TableA a
      ) union all
      (select a.value, count(distinct b.id) as Distinct_B, 0 as Distinct_C
       from TableB b left outer join
            TableA a
            on a.id = b.a_id
       group by a.value
      ) union all
      (select a.value, 0 as Distinct_B, count(distinct c.id) as distinct_C
       from TableC c left outer join
            TableA a 
           on a.id = c.a_id
      )
     ) t

分组a.value

这使用聚合而不是连接来将值组合在一起。