【问题标题】:MySQL Multiple JOIN queryMySQL 多 JOIN 查询
【发布时间】:2013-01-15 17:48:54
【问题描述】:

我有 3 张桌子:

表 A:

  • id int
  • 值变量

表 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。

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

【问题讨论】:

  • 我尝试了 RIGHT JOIN B,它检索了前两列。但是 C 上的下一个连接会破坏一切,因为 C 可以有 B 中缺少的 a_id
  • 你在哪个元素上加入 C 表? (B.a_id 或 A.id)

标签: mysql


【解决方案1】:

由于值非常大,最好在子查询中进行计算:

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

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

【讨论】:

  • 这个子查询似乎无助于丢失空值。 (可能是因为左外连接?)
  • @ziguratahmir 。 . .那些邪恶的 NULL。我将查询修复为可以使用的版本。
猜你喜欢
  • 2013-05-10
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
相关资源
最近更新 更多