1

我有 3 张桌子:

表 A:

  • id int
  • 值 varchar

表 B:

  • id int
  • a_id 默认为空

表 C:

  • id int
  • a_id 不为空

我需要按 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。

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

4

1 回答 1

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 分组

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

于 2013-01-31T15:27:03.310 回答