You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL中HAVING 1语法的含义是什么?分组取最新记录SQL疑问

HAVING 1的含义与实际作用

基础语义

HAVING子句原生作用是在GROUP BY分组操作后,对聚合结果做条件过滤,只有满足HAVING后条件的分组才会被保留。HAVING 1里的1在SQL的布尔判断里等价于恒真,单看这一句的效果是不会过滤任何数据,相当于没写过滤条件。

这段SQL中HAVING 1的真实作用

网上流传的这段SQL是针对5.7及更早版本、未开启ONLY_FULL_GROUP_BY模式的MySQL的特殊写法,HAVING 1在这里没有任何业务过滤价值,纯粹是用来绕过MySQL优化器的默认行为:

  • 按照SQL标准,子查询如果没有搭配LIMIT子句,内层写的ORDER BY会被优化器判定为无意义,会在执行时被忽略。如果去掉这个HAVING,内层写的ORDER BY r.time DESC大概率会被优化掉,外层GROUP BY a.id就不会按预期返回每个id分组下最新的记录。
  • 老版本MySQL的优化器逻辑存在特殊判定:只要子查询里写了HAVING子句,就不会主动消除内层的ORDER BY排序逻辑,会保留按时间倒序排好的结果集,外层GROUP BY时就会默认取每个分组排序后的第一行,刚好得到「每个分组最新一条记录」的效果。

注意事项

  • 这个写法是利用数据库优化器特性的非标准奇技淫巧,兼容性极差:换到8.0及以上版本MySQL、开启ONLY_FULL_GROUP_BY配置、或者换到Oracle/PostgreSQL等其他数据库,这段SQL要么直接报错,要么返回结果不符合预期。
  • 正规的「按字段分组取每组最新记录」的实现不要用这种写法,推荐用窗口函数实现,逻辑清晰且兼容所有主流数据库新版本:
SELECT * FROM (
    SELECT 
        *,
        ROW_NUMBER() OVER (PARTITION BY id ORDER BY time DESC) AS row_rank
    FROM record
    WHERE id IN (xx,xx,xx)
) t
WHERE row_rank = 1

如果是不支持窗口函数的老版本数据库,也可以用关联查询实现:

SELECT r.*
FROM record r
WHERE r.id IN (xx,xx,xx)
AND r.time = (
    SELECT MAX(r2.time) 
    FROM record r2 
    WHERE r2.id = r.id
)

内容的提问来源于stack exchange,提问作者bronson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 22:31:01