按日期范围统计关联表数值遇SQL 1055错误,求正确SQL语句
修正SQL分组错误并实现按日期范围统计求和
现有数据表
1. bayarlanjas表
| tglbayar | bayarlanja | user_id |
|---|---|---|
| 2024-01-05 | 10 | 1 |
| 2024-02-06 | 20 | 1 |
| 2024-03-07 | 30 | 1 |
| 2024-04-08 | 40 | 1 |
2. zakats表
| tglawalhaul | tglakhirhaul | user_id |
|---|---|---|
| 2024-01-01 | 2024-02-25 | 1 |
| 2024-03-01 | 2024-04-25 | 1 |
原SQL语句及错误
需求是按zakats表的日期范围,统计对应user_id的bayarlanja总和,原SQL如下:
SELECT zakats.*, bayarlanjas.user_id, sum(bayarlanja) AS total_bayar FROM `zakats` LEFT JOIN `bayarlanjas` ON `bayarlanjas`.`user_id` = `zakats`.`user_id` WHERE `bayarlanjas`.`tglbayar` BETWEEN zakats.tglawalhaul AND zakats.tglakhirhaul AND `zakats`.`user_id` = 1 GROUP BY `bayarlanjas`.`user_id`
执行后出现错误:
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated
期望查询结果
| tglawalhaul | tglakhirhaul | total_bayar | user_id |
|---|---|---|---|
| 2024-01-01 | 2024-02-25 | 30 | 1 |
| 2024-03-01 | 2024-04-25 | 70 | 1 |
修正后的SQL语句
SELECT z.tglawalhaul, z.tglakhirhaul, z.user_id, COALESCE(SUM(b.bayarlanja), 0) AS total_bayar FROM `zakats` z LEFT JOIN `bayarlanjas` b ON b.user_id = z.user_id AND b.tglbayar BETWEEN z.tglawalhaul AND z.tglakhirhaul WHERE z.user_id = 1 GROUP BY z.tglawalhaul, z.tglakhirhaul, z.user_id
修正说明
- GROUP BY规则适配:原SQL仅按
bayarlanjas.user_id分组,但SELECT中包含zakats.*这类非聚合字段,在开启ONLY_FULL_GROUP_BY模式的MySQL中,所有非聚合字段必须出现在GROUP BY子句里。这里按zakats表的tglawalhaul、tglakhirhaul、user_id分组,确保每个分组对应一个独立的日期区间。 - 保留LEFT JOIN特性:原SQL把日期过滤条件放在WHERE子句中,会导致LEFT JOIN退化为INNER JOIN(WHERE会过滤掉bayarlanjas无匹配的行),将日期条件移到JOIN的ON子句中,可保留zakats表的所有行。
- 空值处理:用
COALESCE将SUM结果转为0,避免某个日期区间无匹配记录时返回NULL。
内容的提问来源于stack exchange,提问作者M. Ade Erik
相关产品推荐
相关产品推荐

