Postgresql
如何對聚合函式呼叫進行排序
如果我有一個昂貴的函式呼叫,它需要一個 JSONB 並返回一個 INT,例如
CREATE FUNCTION my_expensive_function(data JSONB) RETURNS INTEGER AS
如何通過在一組 JSON 數據上呼叫聚合結果來排序聚合結果,例如:
SELECT ARRAY_AGG(my_expensive_function(data) ORDER BY ???) FROM JSONB_ARRAY_ELEMENTS(json_set) data;
如果我嘗試為結果分配名稱,則會收到錯誤消息:
SELECT ARRAY_AGG(my_expensive_function(data) id ORDER BY id) FROM JSONB_ARRAY_ELEMENTS(json_set) data; ERROR: 42601: syntax error at or near "id" LINE 1: SELECT ARRAY_AGG(my_expensive_function(data) id ORDER BY id)... ^ LOCATION: scanner_yyerror, scan.l:1134
我發現我可以通過呼叫該函式兩次來做到這一點,但我討厭這樣:
SELECT ARRAY_AGG(my_expensive_function(data) ORDER BY my_expensive_function(data)) FROM JSONB_ARRAY_ELEMENTS(json_set) data;
我還發現這似乎可行,但也有點麻煩:
WITH data_set AS ( SELECT my_expensive_function(data) AS id FROM JSONB_ARRAY_ELEMENTS(json_set) data ) SELECT ARRAY_AGG(id ORDER BY id) FROM data_set;
更新:我應該指定-我可以在單個查詢中做任何魔術還是必須使用 WITH/子查詢?為什麼我不能在函式的結果中添加名稱?
使用子查詢:
SELECT array_agg(x ORDER BY x) FROM (SELECT my_expensive_function(data) AS x FROM jsonb_array_elements(json_set) AS data ) AS q;
my_expensive_function(data)
另一種選擇是在LATERAL
交叉連接中呼叫:SELECT ARRAY_AGG(id ORDER BY id) FROM JSONB_ARRAY_ELEMENTS(json_set) AS data CROSS JOIN LATERAL (SELECT my_expensive_function(data)) AS x (id) ;
或者,您可以使用逗號表示交叉連接:
SELECT ARRAY_AGG(id ORDER BY id) FROM JSONB_ARRAY_ELEMENTS(json_set) AS data, LATERAL (SELECT my_expensive_function(data)) AS x (id) ;