sql – 如何重用SELECT,WHERE和ORDER BY子句的结果?

以下查询返回我们附近的场地(lat:62.0,lon:25.0),其中我们按照距离排列的半径:
SELECT *,earth_distance(ll_to_earth(62.0,25.0),ll_to_earth(lat,lon)) AS distance 
FROM venues 
WHERE earth_distance(ll_to_earth(62.0,lon)) <= radius 
ORDER BY earth_distance(ll_to_earth(62.0,lon))

是否可以(并且建议)重复使用earth_distance(ll_to_earth(62.0,lon))的结果,而不是单独为SELECT,WHERE和ORDER BY子句计算它?

解决方法

在GROUP BY和ORDER BY子句中,您可以引用列别名(输出列)或甚至SELECT列表项的序号.我引用 the manual on ORDER BY

Each expression can be the name or ordinal number of an output column
(SELECT list item)
,or it can be an arbitrary expression formed from
input-column values.

大胆强调我的.

但是在WHERE和HAVING子句中,您只能引用基表(输入列)中的列,因此您必须拼出函数调用.

SELECT *,lon)) AS dist
FROM   venues 
WHERE  earth_distance(ll_to_earth(62.0,lon)) <= radius 
ORDER  BY distance;

如果您想知道将计算打包到CTE或子查询中是否更快,只需使用EXPLAIN ANALYZE进行测试即可. (我对此表示怀疑.)

SELECT *
FROM  (
   SELECT *,lon)) AS dist
   FROM   venues
   ) x
WHERE  distance <= radius 
ORDER  BY distance;

@Mike commented一样,通过声明函数STABLE(或IMMUTABLE),您可以通知查询计划程序,对于单个语句中的相同调用,函数调用的结果可以重复使用多次.我引用the manual here

A STABLE function cannot modify the database and is guaranteed to
return the same results given the same arguments for all rows within a
single statement. This category allows the optimizer to optimize
multiple calls of the function to a single call
.

大胆强调我的.

相关文章

(一)日志传送架构 (1.1)相关服务器 主服务器 :用于生产的服务器,上面运行这生产SQL Server数据库...
(一)事故背景 最近在SQL Server 2012生产数据库上配置完事物复制(发布订阅)后,生产数据库业务出现了...
(一)测试目的 目前公司使用的SQL SERVER 2012高可用环境为主备模式,其中主库可执行读写操作,备库既...
(一)背景个人在使用sql server时,用到了sql server的发布订阅来做主从同步,类似MySQL的异步复制。在...
UNION和OR谓词 找出 product 和 product2 中售价高于 500 的商品的基本信息. select * from product wh...
datawhale组队学习task03