Postgresql
為什麼 PostgreSQL 中不存在帶有“have”子句的別名?
我正在嘗試計算兩個座標之間的距離並根據一些條件獲取一些資訊。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