Ren*_*ani 92 sql postgresql return return-type plpgsql
我在PostgreSQL中有这个功能,但我不知道如何返回查询结果:
CREATE OR REPLACE FUNCTION wordFrequency(maxTokens INTEGER)
RETURNS SETOF RECORD AS
$$
BEGIN
SELECT text, count(*), 100 / maxTokens * count(*)
FROM (
SELECT text
FROM token
WHERE chartype = 'ALPHABETIC'
LIMIT maxTokens
) as tokens
GROUP BY text
ORDER BY count DESC
END
$$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
但我不知道如何在PostgreSQL函数中返回查询结果.
我发现返回类型应该是SETOF RECORD,对吗?但是返回命令不对.
这样做的正确方法是什么?
Erw*_*ter 115
用途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;
Run Code Online (Sandbox Code Playgroud)
呼叫:
SELECT * FROM word_frequency(123);
Run Code Online (Sandbox Code Playgroud)
说明:
这是很多更实用的明确定义的返回类型不是简单地声明为记录.这样,您不必为每个函数调用提供列定义列表.RETURNS TABLE是一种方法来做到这一点.还有其他人.OUT参数的数据类型必须与查询返回的内容完全匹配.
OUT仔细选择参数名称.它们在功能体中几乎可以在任何地方看到.表限定相同名称的列以避免冲突或意外结果.我在我的例子中为所有列做了那个.
但请注意参数与同名列别名之间的潜在命名冲突.在这种特殊情况下()Postgres在参数中使用列别名.但是,在其他情况下,这可能是模棱两可的.有各种方法可以避免任何混淆:OUTcntRETURN QUERY SELECT ...OUT
ORDER BY 2 DESC.例:
ORDER BY count(*).plpgsql.variable_conflict或使用#variable_conflict error | use_variable | use_column每个功能的特殊命令.例:
不要使用"text"和"count"作为列名.两者在Postgres中都是合法的,但"count"是标准SQL中的保留字和基本函数名,"text"是基本数据类型.可能导致混乱的错误.我用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;
Run Code Online (Sandbox Code Playgroud)
表达式sum(t.cnt) OVER ()是一个窗口函数.您可以使用CTE而不是子查询 - 漂亮,但在这样的简单情况下,子查询通常更便宜.
最后明确RETURN声明不要求有工作的时候(但允许)OUT参数或RETURNS TABLE(使隐式使用的OUT参数).
round()两个参数仅适用于numeric类型.count()子查询产生bigint的结果和sum()在此bigint产生numeric的结果,因此,我们对付numeric自动编号和一切都只是属于地方.
小智 9
请参阅以下链接获取文档:
https://www.postgresql.org/docs/current/xfunc-sql.html
例子:
CREATE FUNCTION sum_n_product_with_tab (x int)
RETURNS TABLE(sum int, product int) AS $$
SELECT $1 + tab.y, $1 * tab.y FROM tab;
$$ LANGUAGE SQL;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
139728 次 |
| 最近记录: |