MySQL LEFT JOIN带COUNT统计时AND条件的正确放置方法
核心原因
把Table_2.CONDITION = 1写在WHERE子句中会过滤掉所有Table_2字段为NULL的行——也就是那些没有匹配到Table_2记录的Table_1数据,最终LEFT JOIN会退化成INNER JOIN,自然没法保留Table_1的全部行。
正确实现方式
两种方案都能满足需求,按需选择即可:
方案1:把右表筛选条件放到LEFT JOIN的ON子句后
在关联阶段就只匹配Table_2中满足CONDITION=1的记录,没有匹配到的Table_1行依然会保留,只是对应Table_2的字段值为NULL,COUNT统计时会自动忽略NULL值,得到正确计数。
SELECT `Table_1`.`ID`, `Table_1`.`ARRIVAL`, COUNT(`Table_2`.`DATE`) AS My_COUNT FROM `Table_1` LEFT JOIN `Table_2` ON `Table_1`.`ARRIVAL` = `Table_2`.`DATE` AND `Table_2`.`CONDITION` = 1 -- 右表筛选条件直接写在关联条件后 WHERE `Table_1`.`DEPARTED` = 0 GROUP BY `Table_1`.`ID`, `Table_1`.`ARRIVAL`;
方案2:使用条件聚合,在COUNT时做判断
不修改原有JOIN逻辑,只在聚合函数内判断记录是否满足条件,COUNT会自动忽略不满足条件时返回的NULL值:
SELECT `Table_1`.`ID`, `Table_1`.`ARRIVAL`, COUNT(CASE WHEN `Table_2`.`CONDITION` = 1 THEN `Table_2`.`DATE` END) AS My_COUNT FROM `Table_1` LEFT JOIN `Table_2` ON `Table_1`.`ARRIVAL` = `Table_2`.`DATE` WHERE `Table_1`.`DEPARTED` = 0 GROUP BY `Table_1`.`ID`, `Table_1`.`ARRIVAL`;
两种写法返回结果完全符合预期:
| ID | ARRIVAL | My_Count |
|---|---|---|
| 1 | 2022-07-24 | 2 |
| 2 | 2022-07-25 | NULL |
| 3 | 2022-07-28 | 1 |
| 4 | 2022-07-24 | 2 |
补充说明:MySQL默认开启的宽松GROUP BY模式允许仅按主键分组,但从SQL规范和兼容性角度,建议SELECT中非聚合字段都加入GROUP BY子句,避免不同环境下出现语法错误。
内容的提问来源于stack exchange,提问作者TV-C-1-5
相关产品推荐
相关产品推荐

