雖然從MySQL 5.5轉換到PostgreSQL 9.4,我有問題,與此查詢:如何在HAVING子句中使用函數的輸出?
SELECT *, GCDist(?, ?, lat, lon) AS dist
FROM ads
HAVING dist < radius
ORDER BY date_created DESC
LIMIT ?;
其中GCDist
計算兩點間的大圓距離。
沒有HAVING
子句,查詢工作的Postgres的罰款,但如果我想與dist > radius
篩選出的行我收到此錯誤:
ERROR: column "dist" does not exist
LINE 1: ...*, GCDist(0, 0, lat, lon) AS dist FROM ads HAVING dist < 100...
是否可以使用函數的輸出在PostgreSQL 9.4中查詢的HAVING
子句中?如果是這樣,怎麼樣?
非常感謝您提供任何提示。
下面是如何重現錯誤:
CREATE FUNCTION GCDist (
_lat1 FLOAT, -- Scaled Degrees north for one point
_lon1 FLOAT, -- Scaled Degrees west for one point
_lat2 FLOAT, -- other point
_lon2 FLOAT
) RETURNS FLOAT
IMMUTABLE AS
$$
-- Hardcoded constant:
DECLARE
_deg2km FLOAT DEFAULT 0.0111325;
_deg2rad FLOAT DEFAULT PI()/1800000; -- For scaled by 1e4 to MEDIUMINT
_rlat1 FLOAT DEFAULT _deg2rad * _lat1;
_rlat2 FLOAT DEFAULT _deg2rad * _lat2;
-- compute as if earth's radius = 1.0
_rlond FLOAT DEFAULT _deg2rad * (_lon1 - _lon2);
_m FLOAT DEFAULT COS(_rlat2);
_x FLOAT DEFAULT COS(_rlat1) - _m * COS(_rlond);
_y FLOAT DEFAULT _m * SIN(_rlond);
_z FLOAT DEFAULT SIN(_rlat1) - SIN(_rlat2);
_n FLOAT DEFAULT SQRT(_x * _x + _y * _y + _z * _z);
BEGIN
RETURN _deg2km * 2 * ASIN(_n/2)/_deg2rad; -- again--scaled degrees
END;
$$
LANGUAGE plpgsql;
CREATE TABLE test (id SERIAL PRIMARY KEY, lat INTEGER NOT NULL, lon INTEGER NOT NULL);
INSERT INTO test (id, lat, lon) VALUES (DEFAULT, 10000, 10000);
INSERT INTO test (id, lat, lon) VALUES (DEFAULT, 20000, 20000);
INSERT INTO test (id, lat, lon) VALUES (DEFAULT, 50000, 50000);
SELECT *, GCDist(0, 0, lat, lon) AS dist FROM test HAVING dist < 200;
MySQL的輸出表將類似於以下內容:
id | lat | lon | dist
---+-----+-----+------
1 |10000|10000|157.43
那麼,從我理解的情況來看,在MySQL中,區別在於執行順序(WHERE在函數執行之前選擇,而HAVING選擇之後),所以HAVING是唯一的方法。 關於你的第一個建議,是不是子查詢「昂貴」?我的意思是,爲什麼數據庫管理系統應該爲這個計算創建另一個表格,何時它可以簡單地附加這些值? (我不知道如何優化查詢,但基於語法,它似乎更慢) 關於你的第二個建議,'GCDist'會執行兩次嗎?因爲如果是這樣,我不能使用它。這個功能已經很慢了。 –
@CarloVespa,你有沒有試過a_horse_with_no_name的解決方案?檢查執行時間。你會感到驚訝,因爲優化器比你想象的要好。 –
@EmacsUser是的,我目前正在使用他的第一個解決方案。我知道優化器是好的,但對我來說,看起來很尷尬,所以你需要兩個'SELECT'來做這麼簡單的事情。 –