Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using function result in WHERE clause in PostgreSQL

I am trying to use result of function execution in where clause but with no success:

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

gives me:Column "dist" does not exists. Quoting it like:

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

doesn't helps either. Please advise is there possibility in Postgres to use function result in WHERE clause without calling it twice? Thanks!

like image 269
Serj.by Avatar asked Nov 23 '17 12:11

Serj.by


People also ask

Can we call a function inside a function in PostgreSQL?

In EDB Postgres Advanced Server 9.6, you can write a nested function or procedure within: Function. Procedure. Trigger.

Can PostgreSQL stored procedure return resultset?

Both stored procedures and user-defined functions are created with CREATE FUNCTION statement in PostgreSQL. To return one or more result sets (cursors in terms of PostgreSQL), you have to use refcursor return type.

What is $$ in PostgreSQL function?

It can be used to replace single quotes enclosing string literals (constants) anywhere in SQL scripts. The body of a function happens to be such a string literal. Dollar-quoting is a PostgreSQL-specific substitute for single quotes to avoid escaping of nested single quotes (recursively).

Can we call stored procedure from function in PostgreSQL?

PostgreSQL does not support true stored procedures (multiple result sets, autonomous transactions, and all that) though, only sql-callable user-defined functions.


1 Answers

To avoid calling distance_between_objects twice:

--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 is a cleaner approach in my opinion.

like image 94
Michel Milezzi Avatar answered Sep 29 '22 07:09

Michel Milezzi