同时使用LEFT JOIN和GROUP BY查询无结果,SQL逻辑错误排查
LEFT JOIN与GROUP BY联用问题排查
需求说明
关联job_timetable与call_log两张表(公共关联字段为user_id),实现两个统计需求:
- 对
job_timetable按user_id分组,计算每组counter列的总和 - 对
call_log按user_id分组,计算每组duration列的总和与平均值
示例数据
call_log 表
user_id duration 5019 12 2345 23 5019 14
job_timetable 表
user_id counter 5019 1 5019 3 2345 2
预期输出
user_id duration average duration countersum 5019 26 13 4 2345 23 23 2
原错误SQL
SELECT call_log.user_id,SUM(call_log.duration) as duration,avg(call_log.duration) as average_duration,countersum FROM call_log LEFT JOIN (SELECT user_id,sum(counter) as countersum FROM job_timetable GROUP BY user_id ) b on call_log.user_id= b.user_id where call_log.user_id is not null group by call_log.user_id order by call_log.user_id asc;
问题排查
拿到空结果的核心原因是原SQL不符合标准SQL语法规范,触发了数据库的语法校验错误,无法正常执行返回结果:
绝大多数数据库(如开启ONLY_FULL_GROUP_BY模式的MySQL、PostgreSQL、Oracle等)要求SELECT子句中所有非聚合字段,必须全部出现在GROUP BY子句中。你在SELECT中直接引用了子查询返回的countersum字段,该字段既没有包含在GROUP BY子句里,也没有被聚合函数包裹,直接触发语法报错。
修正后SQL
建议先分别对两张表做聚合计算,再做关联,逻辑更严谨,也不会触发语法问题:
SELECT a.user_id, a.duration, a.average_duration, b.countersum FROM ( -- 先聚合call_log得到每个用户的通话统计数据 SELECT user_id, SUM(duration) AS duration, AVG(duration) AS average_duration FROM call_log WHERE user_id IS NOT NULL GROUP BY user_id ) a LEFT JOIN ( -- 先聚合job_timetable得到每个用户的counter总和 SELECT user_id, SUM(counter) AS countersum FROM job_timetable GROUP BY user_id ) b ON a.user_id = b.user_id ORDER BY a.user_id ASC;
内容的提问来源于stack exchange,提问作者Surya Singh
相关产品推荐
相关产品推荐

