You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多次LEFT JOIN后按b.id和c.id分组统计B、C表行数的方法

解决方案

要避免直接关联后因笛卡尔积导致的统计错误,建议先对B、C表分别按ID预聚合统计行数,再与A表关联,最后按b.id和c.id分组(注:若某ID在B/C中无匹配,对应字段会返回NULL):

SELECT
    COALESCE(b.id, '无B表匹配') AS B_ID,
    COALESCE(c.id, '无C表匹配') AS C_ID,
    SUM(b.b_cnt) AS B_CNT,
    SUM(c.c_cnt) AS C_CNT
FROM A
LEFT JOIN (
    SELECT id, COUNT(*) AS b_cnt
    FROM B
    GROUP BY id
) b ON A.id = b.id
LEFT JOIN (
    SELECT id, COUNT(*) AS c_cnt
    FROM C
    GROUP BY id
) c ON A.id = c.id
GROUP BY b.id, c.id;

关键说明

  • 子查询先对B、C表按ID统计行数,彻底避免了直接JOIN后产生的笛卡尔积导致重复计数的问题,这是效率最高的方案。
  • COALESCE函数用于将NULL值替换为易读文本,若不需要可以直接保留NULL,根据业务需求调整即可。

备选方案(仅适用于特定场景)

如果你的业务逻辑允许忽略笛卡尔积影响,或仅需统计存在关联的记录数,也可以用COUNT(DISTINCT)修正计数,但这种方式效率低于预聚合:

SELECT
    b.id AS B_ID,
    c.id AS C_ID,
    COUNT(DISTINCT b.唯一标识字段) AS B_CNT, -- 建议用B表的主键而非id,避免同id多重复记录的统计误差
    COUNT(DISTINCT c.唯一标识字段) AS C_CNT
FROM A
LEFT JOIN B ON A.id = B.id
LEFT JOIN C ON A.id = C.id
GROUP BY b.id, c.id;

注意:如果B/C表中同一id对应多条记录,直接用COUNT(*)会因笛卡尔积导致结果偏大,必须用COUNT(DISTINCT 主键)或预聚合的方式修正。

内容的提问来源于stack exchange,提问作者SH Kwon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 04:50:26