SQL查询附近地点时提示'distance'列不存在的问题
解决SQL查询附近地点时"column 'distance' does not exist"错误
我尝试执行一条查询当前位置附近地点的SQL语句,但每次运行都会返回错误:
column "distance" does not exist
如果删除HAVING和ORDER BY子句,只保留到FROM posts的部分,查询能正常返回post id和distance列;但保留原语句结构就会触发这个错误。原SQL语句如下:
SELECT id, ( 3959 * acos( cos( radians(-32.63) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(-71.42) ) + sin( radians(-32.63) ) * sin( radians( latitude ) ) ) ) AS distance FROM posts HAVING distance < 25 ORDER BY distance;
问题原因
SQL的执行顺序是FROM→WHERE→GROUP BY→HAVING→SELECT→ORDER BY。当执行到HAVING子句时,SELECT里定义的别名distance还没被生成,数据库自然找不到这个列,所以报错。另外这里没有分组操作,用HAVING本身就不符合SQL语义,应该用WHERE来过滤行级数据。
解决办法
方法一:重复计算逻辑到过滤条件中
直接把SELECT中计算distance的表达式复制到过滤条件里:
SELECT id, ( 3959 * acos( cos( radians(-32.63) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(-71.42) ) + sin( radians(-32.63) ) * sin( radians( latitude ) ) ) ) AS distance FROM posts WHERE ( 3959 * acos( cos( radians(-32.63) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(-71.42) ) + sin( radians(-32.63) ) * sin( radians( latitude ) ) ) ) < 25 ORDER BY distance;
缺点是同一个计算逻辑执行两次,数据量大时性能会受影响。
方法二:用子查询先计算distance再过滤(推荐)
先通过子查询生成包含distance的临时结果集,再对结果集进行过滤和排序:
SELECT id, distance FROM ( SELECT id, ( 3959 * acos( cos( radians(-32.63) ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians(-71.42) ) + sin( radians(-32.63) ) * sin( radians( latitude ) ) ) ) AS distance FROM posts ) AS post_with_distance WHERE distance < 25 ORDER BY distance;
这种写法只计算一次distance,逻辑清晰,性能更优,也符合SQL的语义规范。
内容的提问来源于stack exchange,提问作者Richi
相关产品推荐
相关产品推荐

