SQL查询执行顺序解惑:为何该HAVING子句查询能正常运行?
为什么HAVING子句能使用SELECT中定义的别名?
首先是数据表的创建与插入语句:
CREATE TABLE exercise_logs (id INTEGER PRIMARY KEY AUTOINCREMENT, type TEXT, minutes INTEGER, calories INTEGER, heart_rate INTEGER); INSERT INTO exercise_logs(type, minutes, calories, heart_rate) VALUES ("biking", 30, 115, 110); INSERT INTO exercise_logs(type, minutes, calories, heart_rate) VALUES ("biking", 10, 45, 105); INSERT INTO exercise_logs(type, minutes, calories, heart_rate) VALUES ("dancing", 15, 200, 120); INSERT INTO exercise_logs(type, minutes, calories, heart_rate) VALUES ("dancing", 15, 165, 120); INSERT INTO exercise_logs(type, minutes, calories, heart_rate) VALUES ("tree climbing", 30, 70, 90); INSERT INTO exercise_logs(type, minutes, calories, heart_rate) VALUES ("tree climbing", 25, 72, 80); INSERT INTO exercise_logs(type, minutes, calories, heart_rate) VALUES ("rowing", 30, 70, 90); INSERT INTO exercise_logs(type, minutes, calories, heart_rate) VALUES ("hiking", 60, 80, 85);
执行的查询语句:
SELECT type, AVG(calories) AS avg_calories FROM exercise_logs GROUP BY type HAVING avg_calories > 70;
问题
按照标准SQL执行顺序,GROUP BY和HAVING的执行逻辑先于SELECT,照理说avg_calories这个别名是在SELECT里定义的,HAVING阶段应该还未识别到该别名,为什么这条语句能正常运行?
解答
这是因为不同SQL数据库的语法解析器做了特殊兼容处理,并非所有数据库都支持这种写法,但像SQLite(本示例使用的数据库)、MySQL等常用数据库允许在HAVING子句中直接引用SELECT里定义的列别名。
从SQL标准定义来看,HAVING子句仅能引用GROUP BY中的分组列,或者直接写聚合函数表达式。但实际实现中,很多数据库会先解析SELECT子句中的别名,将其与对应的聚合表达式做绑定,这样HAVING就能直接使用别名替代重复书写聚合函数,提升SQL的可读性与易用性。
本质上这是数据库厂商对标准SQL的扩展支持,虽不符合严格的执行顺序逻辑,但在实际开发中被广泛应用。
内容的提问来源于stack exchange,提问作者Imahn
相关产品推荐
相关产品推荐

