2 回答

TA貢獻1829條經驗 獲得超7個贊
用途RETURN QUERY:
CREATE OR REPLACE FUNCTION word_frequency(_max_tokens int)
RETURNS TABLE (txt text -- also visible as OUT parameter inside function
, cnt bigint
, ratio bigint) AS
$func$
BEGIN
RETURN QUERY
SELECT t.txt
, count(*) AS cnt -- column alias only visible inside
, (count(*) * 100) / _max_tokens -- I added brackets
FROM (
SELECT t.txt
FROM token t
WHERE t.chartype = 'ALPHABETIC'
LIMIT _max_tokens
) t
GROUP BY t.txt
ORDER BY cnt DESC; -- potential ambiguity
END
$func$ LANGUAGE plpgsql;
呼叫:
SELECT * FROM word_frequency(123);
說明:
這是很多更實用的明確定義的返回類型不是簡單地聲明為記錄。這樣,您不必在每次函數調用時都提供列定義列表。RETURNS TABLE是做到這一點的一種方法。還有其他 OUT參數的數據類型必須與查詢返回的內容完全匹配。
OUT仔細選擇參數名稱。它們在功能主體中幾乎任何位置都可見。對具有相同名稱的列進行表限定,以避免沖突或意外結果。我在示例中對所有列進行了此操作。
但是請注意,參數和同名列別名之間可能存在命名沖突。在這種特殊情況下(),Postgres會以兩種方式在參數上使用列別名。但是,在其他情況下,這可能是模棱兩可的。有多種避免混淆的方法:OUTcntRETURN QUERY SELECT ...OUT
使用項目在SELECT列表中的順序位置:ORDER BY 2 DESC。例:
在每個GROUP BY組中選擇第一行?
重復表達式ORDER BY count(*)。
(此處不適用。)設置配置參數plpgsql.variable_conflict或#variable_conflict error | use_variable | use_column在功能中使用特殊命令??吹剑?/p>
使用USING子句命名函數參數和JOIN結果之間的沖突
請勿使用“文本”或“計數”作為列名。兩者在Postgres中都是合法使用的,但是“ count”是標準SQL中的保留字,并且是基本函數名稱,而“ text”是基本數據類型??赡軐е禄靵y的錯誤。我在示例中使用txt和cnt。
添加了缺少的內容,;并糾正了標頭中的語法錯誤。(_max_tokens int)不(int maxTokens)- 鍵入后的名稱。
使用整數除法時,最好先相乘然后再相除,以最大程度地減少舍入誤差。甚至更好:使用numeric(或浮點類型)。見下文。
另類
我認為您的查詢實際上應該是這樣的(計算每個令牌的相對份額):
CREATE OR REPLACE FUNCTION word_frequency(_max_tokens int)
RETURNS TABLE (txt text
, abs_cnt bigint
, relative_share numeric) AS
$func$
BEGIN
RETURN QUERY
SELECT t.txt, t.cnt
, round((t.cnt * 100) / (sum(t.cnt) OVER ()), 2) -- AS relative_share
FROM (
SELECT t.txt, count(*) AS cnt
FROM token t
WHERE t.chartype = 'ALPHABETIC'
GROUP BY t.txt
ORDER BY cnt DESC
LIMIT _max_tokens
) t
ORDER BY t.cnt DESC;
END
$func$ LANGUAGE plpgsql;
該表達式sum(t.cnt) OVER ()是一個窗口函數。您可以使用CTE代替子查詢-漂亮,但是在這種簡單情況下,子查詢通常更便宜。
最后明確RETURN聲明不要求有工作的時候(但允許)OUT參數或RETURNS TABLE(使隱式使用的OUT參數)。
round()具有兩個參數的參數僅適用于numeric類型。count()子查詢產生bigint的結果和sum()在此bigint產生numeric的結果,因此,我們對付numeric自動編號和一切都只是屬于地方。
- 2 回答
- 0 關注
- 1900 瀏覽
添加回答
舉報