MySQL GROUP BY中使用MAX函数筛选数据报错求助
解决MySQL中基于分组最大日期筛选记录的问题
嘿,我来帮你搞定这个MySQL的筛选问题!你遇到的报错,核心原因是内层子查询根本拿不到外层分组计算出来的max_date——SQL的执行顺序是先跑WHERE子句,再做GROUP BY,所以你在WHERE里引用GROUP BY生成的别名,MySQL肯定认不出来呀。
咱们换个思路:先把每个t1_id对应的最大date_created算出来,再用这个值去筛选t2表的记录就好啦,给你两种可行的方法:
方法一:兼容所有MySQL版本的写法
先单独算出每个分组的最大日期,再和t2表关联筛选:
SELECT t2.* FROM t2 JOIN ( -- 先搞定每个t1_id对应的最大date_created SELECT t1_id, MAX(date_created) AS max_date_created FROM t2 GROUP BY t1_id ) AS t2_grouped ON t2.t1_id = t2_grouped.t1_id -- 筛选规则:要么不是status_id=17的记录,要么是但status_change_date不小于分组最大日期 WHERE NOT (t2.status_id = 17 AND t2.status_change_date < t2_grouped.max_date_created);
方法二:用窗口函数简化(MySQL 8.0及以上可用)
如果你的MySQL版本比较新(8.0+),用窗口函数会更简洁,不用单独写子查询关联:
SELECT id, t1_id, status_change_date, status_id, date_created FROM ( SELECT t2.*, -- 按t1_id分组,直接算出当前分组的最大date_created MAX(date_created) OVER (PARTITION BY t1_id) AS max_date_created FROM t2 ) AS t2_with_max WHERE NOT (status_id = 17 AND status_change_date < max_date_created);
测试结果验证
用你给的测试数据跑上面任意一段SQL,都会得到你想要的结果:
| id | t1_id | status_change_date | status_id | date_created |
|---|---|---|---|---|
| 3 | 1 | 2010-02-12 | 17 | 2007-02-12 |
为啥原来的SQL会报错?
再给你捋清楚:你原来的SQL里,内层子查询SELECT t2.id FROM t2 WHERE status_id = 17 and status_change_date < max_date里的max_date是外层GROUP BY生成的别名,但SQL执行的时候,WHERE子句会先于GROUP BY执行,这时候max_date还没被计算出来呢,MySQL当然不知道这个变量是啥,所以就报错啦。咱们先预计算分组最大日期,再做筛选,就完美避开这个问题啦。
内容的提问来源于stack exchange,提问作者Alexander Karp
相关产品推荐
相关产品推荐

