MySQL GROUP BY后子查询IN条件如何使用被聚合的父表ID值
可行解决方案按适配优先级排序如下:
方案1:MySQL 8.0+ 适用CTE预聚合(推荐)
先按parent.id维度预计算关联的child手指总和,再外层按需要的分组维度聚合,完全避免多表关联行重复问题,且子查询命中child.parent_id索引的情况下性能极高,也兼容动态生成的多类GROUP BY组合,无需重构核心逻辑:
WITH per_parent_agg AS ( SELECT p.*, (SELECT SUM(fingers) FROM child c WHERE c.parent_id = p.id) AS parent_total_fingers FROM parent p ) SELECT first_name, SUM(parent_total_fingers) AS kid_fingers FROM per_parent_agg GROUP BY first_name;
方案2:低版本MySQL适配FIND_IN_SET + GROUP_CONCAT
比REGEXP匹配安全度高,仅需调整IN条件为FIND_IN_SET逻辑,原有查询结构几乎不用修改:
注意提前调整会话级
group_concat_max_len参数,避免分组内id过多被截断:SET SESSION group_concat_max_len = 1000000; -- 按实际业务id数量调整大小
修改后的查询语句:
SELECT parent.first_name, ( SELECT SUM(fingers) FROM child WHERE FIND_IN_SET(child.parent_id, GROUP_CONCAT(DISTINCT parent.id SEPARATOR ',')) ) AS kid_fingers FROM parent GROUP BY parent.first_name;
方案3:子查询关联分组字段过滤
不需要处理折叠的id列表,直接用当前分组的first_name反查同组所有parent的关联记录:
SELECT parent.first_name, ( SELECT SUM(c.fingers) FROM child c INNER JOIN parent p2 ON c.parent_id = p2.id WHERE p2.first_name = parent.first_name ) AS kid_fingers FROM parent GROUP BY parent.first_name;
该方案适合parent.first_name区分度较高、建有索引的场景。
内容的提问来源于stack exchange,提问作者Rikaelus
相关产品推荐
相关产品推荐

