Postgresql

為什麼 PostgreSQL 中不存在帶有“have”子句的別名?

  • December 17, 2020

我正在嘗試計算兩個座標之間的距離並根據一些條件獲取一些資訊。MySQL 中也有一個類似的帶有“having”子句的查詢。但為什麼它在 PostgreSQL 中不起作用?

這是我的查詢:

   SELECT *, ( 6371 * acos( cos( radians(latitude) ) * cos( radians( latitude1 ) ) *
   cos( radians( longitude1 ) - radians(longitude) ) + sin( radians(latitude) ) *
   sin( radians( latitude1 ) ) ) ) AS distance from table WHERE
   verified=true AND best_for LIKE '%xyz%' AND uuid NOT IN (SELECT uuid::uuid FROM table2 WHERE
   from_date BETWEEN '2020-12-17 06:30'::date AND '2020-12-18 12:30'::date AND
   to_date BETWEEN '2020-12-17 06:30'::date AND '2020-12-18 12:30'::date  AND )
   HAVING distance < 50 ORDER BY distance

為什麼距離不存在?以及如何修改此查詢以使其在 PostgreSQL 中工作?

這是 SQL 標准設置的規則(並且 MySQL 忽略了標准定義的一些規則並允許無效的 SQL)。

您不能在定義它的同一級別上使用列別名,並且having只能在使用聚合的查詢中使用。如果要避免重複表達式,請使用派生表。

它通常使用起來也更快,NOT EXISTS而不是NOT IN

SELECT *
FROM (
 SELECT *, 
       ( 6371 * acos( cos( radians(latitude) ) * cos( radians( latitude1 ) ) * 
         cos( radians( longitude1 ) - radians(longitude) ) + sin( radians(latitude) ) * 
         sin( radians( latitude1 ) ) ) ) AS distance 
 from table t1
 WHERE verified = true 
   AND best_for LIKE '%xyz%' 
   AND NOT EXISTS (SELECT *
                    FROM table2 t2
                    WHERE t2.from_date BETWEEN '2020-12-17 06:30'::date AND '2020-12-18 12:30'::date 
                      AND t2.to_date BETWEEN '2020-12-17 06:30'::date AND '2020-12-18 12:30'::date  
                      AND t2.uuid::uuid = t1.uuid)
) x                       
WHERE distance < 50 
ORDER BY distance

引用自:https://dba.stackexchange.com/questions/281438