SQL中WHERE子句用列别名报'Unrecognized Name'错误的解决办法
问题解决:WHERE子句无法使用聚合函数或其别名的问题
错误原因
SQL的执行顺序决定了WHERE子句在聚合函数计算之前执行,此时SELECT里定义的别名(比如num_of_trips)还未生成,直接在WHERE里写聚合函数(比如AVG())也会因为数据还未完成聚合而报错。
解决方案
根据你的查询场景,分两种情况处理:
1. 分组查询场景(按某字段分组后筛选聚合结果)
如果是需要筛选分组后符合聚合条件的数据(比如每个起始站点的行程数大于30、平均时长超过30分钟),直接使用HAVING子句替代WHERE——HAVING是在聚合计算完成后执行的,能识别聚合函数:
SELECT start_station, COUNT(*) AS num_of_trips, ROUND(AVG(tripduration/60), 2) AS avg_duration FROM trips GROUP BY start_station HAVING COUNT(*) > 30 AND ROUND(AVG(tripduration/60), 2) > 30;
注:部分数据库支持在HAVING中直接使用SELECT里的别名(比如num_of_trips > 30),但为了兼容性,建议直接写聚合函数表达式。
2. 全局聚合筛选场景(筛选整个表符合全局聚合条件的数据)
如果是需要基于全表聚合结果筛选数据(比如全表总行程数大于30、全表平均时长超过30分钟),可以用子查询或CTE先计算聚合值,再在外部WHERE中筛选:
子查询写法:
SELECT * FROM ( SELECT *, COUNT(*) OVER() AS num_of_trips, ROUND(AVG(tripduration/60) OVER(), 2) AS avg_duration FROM trips ) AS sub_query WHERE num_of_trips > 30 AND avg_duration > 30;
CTE写法(更易读):
WITH trip_summary AS ( SELECT *, COUNT(*) OVER() AS num_of_trips, ROUND(AVG(tripduration/60) OVER(), 2) AS avg_duration FROM trips ) SELECT * FROM trip_summary WHERE num_of_trips > 30 AND avg_duration > 30;
这里用OVER()窗口函数计算全表的聚合值,生成别名后就能在WHERE中正常调用。
内容的提问来源于stack exchange,提问作者devendande
相关产品推荐
相关产品推荐

