在 PostgreSQL 的 WHERE 子句中使用函数结果

Posted

技术标签:

【中文标题】在 PostgreSQL 的 WHERE 子句中使用函数结果【英文标题】:Using function result in WHERE clause in PostgreSQL 【发布时间】:2018-05-07 10:43:34 【问题描述】:

我正在尝试在where 子句中使用函数执行的结果,但没有成功:

SELECT clinics.*, distance_between_objects(1, id, 7, 3) AS dist FROM clinics WHERE dist<=1;

给我:Column "dist" does not exists。 像这样引用它:

SELECT clinics.*, distance_between_objects(1, id, 7, 3) AS dist FROM clinics WHERE "dist"<=1;

也无济于事。请告知 Postgres 是否有可能在 WHERE 子句中使用函数结果而不调用它两次? 谢谢!

【问题讨论】:

WHERE 不能使用在同一级别的 select 中计算的值,因为它是在获取值之前进行评估的。另一方面 ORDER BY 可以,因为它是在选择所有值之后评估的。但是将函数封装到 FROM 子句中的子选择中,它会起作用。 【参考方案1】:

为了避免两次调用distance_between_objects

--Subquery
SELECT * FROM (
    SELECT 
        *, 
        distance_between_objects(1, id, 7, 3) AS dist 
    FROM 
        clinics) AS clinics_dist 
WHERE 
    dist <= 1;

--CTE
WITH clinics_dist AS (
    SELECT 
        *, 
        distance_between_objects(1, id, 7, 3) AS dist 
    FROM 
        clinics
)
SELECT 
    * 
FROM 
    clinics_dist 
WHERE 
    dist <= 1;

CTE 在我看来是一种更简洁的方法。

【讨论】:

【参考方案2】:

您也可以使用 LATERAL

SELECT *
FROM clinics,
LATERAL (SELECT distance_between_objects(1, id, 7, 3) AS dist) l
WHERE l.dist <= 1;

【讨论】:

【参考方案3】:

可以在where子句中使用函数:

SELECT clinics.*, distance_between_objects(1, id, 7, 3) AS dist 
FROM clinics 
WHERE distance_between_objects(1, id, 7, 3)<=1;

【讨论】:

目标是不调用函数两次。就像上面 michel.milezzi 的回答一样。 但是为了不调用函数两次,你通过数据库进行多次运行(子查询、排序和使用临时空间)来结束。有时,更简洁的代码并不是更高效的数据库。无论如何,据我所知,除非您在其上创建函数索引,否则将函数放在查询左侧的字段中是不高效的。这适用于所有解决方案

以上是关于在 PostgreSQL 的 WHERE 子句中使用函数结果的主要内容,如果未能解决你的问题,请参考以下文章

PostgreSQL WHERE 子句

PostgreSQL WHERE 子句

PostgreSQL 函数不适用于 WHERE 子句

Postgresql 包含在 where 子句中

在 postgreSQL 中使用 WHERE 子句创建三个表的最有效方法是啥

PostgreSQL:在 WHERE 子句中搜索时列不存在