0

我正在尝试在用户定义的函数中将数字变量调用/转换为字符串。我正在考虑使用to_char,但它没有通过。

我的功能是这样的:

create or replace function ntile_loop(x numeric)
returns setof numeric as 
$$
  select

  max("billed") as _____(to_char($1,'99')||"%"???) from 
      (select "billed", "id","cm",ntile(100) 
      over (partition by "id","cm" order by "billed")
      as "percentile" from "table_all") where "percentile"=$1
      group by "id","cm","percentile";
$$
language sql;

我的目的是定义一个新变量“x%”作为其名称,其中 x 变化作为函数输入。在上下文中,x 是数字,稍后将在函数中作为数字再次调用(这部分代码未包含在上面的示例中)。

我要返回的内容:

我只是想返回一段代码,这样每次我更改百分位数时,我就不必一次又一次地运行这段代码。我想计算 5, 10, 20, 30, ....90th 百分位数,并将每个 id+cm 组的所有这些都显示在同一张表中。

这就是为什么我在考虑宏或函数,但没有找到我喜欢的任何解决方案。

谢谢您的回答。是的,我一定会在学习的同时阅读基础知识。今天是我使用 SQL 的第二天,但必须立即生成一些结果。

4

2 回答 2

2

转换numerictext是最少的问题。

我的目的是定义一个新变量“x%”作为其名称,其中 x 变化作为函数输入。

  • 首先:SQL 函数中没有变量。SQL 函数只是有效 SQL 语句的包装器。输入和输出参数可以命名,但名称是静态的,而不是动态的。

  • 您可能正在考虑一个PL/pgSQL函数,其中有包括变量在内的过程元素。不过,参数名称仍然是static。plpgsql 中没有动态变量名。您可以执行动态 SQL,EXECUTE但这完全不同。

  • 虽然可以声明一个具有类似名称的静态变量,但这样做非常罕见。也许是为了故意混淆代码?除此之外:不要。使用正确的、简单的、合法的、小写的变量名,而不需要双引号,也不会在错字后做一些意想不到的事情。"123%"

  • 由于窗口函数ntile()返回integer并且您对结果运行相等性检查,因此输入参数应该是integer,而不是numeric

  • 在 plpgsql 中分配变量,:=您可以对单个变量或SELECT INTO任意数量的变量使用赋值运算符。无论哪种方式,您都希望查询返回单行,或者您必须循环

  • 如果您想要billed所选百分位数的最大值,则不需要GROUP BY x, y. 这可能会返回多行并且不会执行您想要的操作。使用plain max(billed)withoutGROUP BY获得单行。

  • 您不需要双引号完全合法的列名

一个有效的函数可能看起来像这样。这不完全是你想要做的,这是无法做到的。但它可能会让你更接近你真正需要的东西。

CREATE OR REPLACE FUNCTION ntile_loop(x integer)
RETURNS SETOF numeric as 
$func$
DECLARE
   myvar text;
BEGIN

SELECT INTO myvar  max(billed)
FROM  (
   SELECT billed, id, cm
         ,ntile(100) OVER (PARTITION BY id, cm ORDER BY billed) AS tile
   FROM   table_all
   ) sub
WHERE  sub.tile = $1;

-- do something with myvar, depending on the value of $1 ...
END
$func$ LANGUAGE plpgsql;

长话短说,在尝试创建复杂功能之前,您需要学习基础知识。

纯 SQL

Q更新后:

我想计算 5, 10, 20, 30, ....90th 百分位数,并将每个 id+cm 组的所有这些都显示在同一张表中。

这个简单的查询应该可以完成所有工作:

SELECT id, cm, tile, max(billed) AS max_billed
FROM  (
   SELECT billed, id, cm
         ,ntile(100) OVER (PARTITION BY id, cm ORDER BY billed) AS tile
   FROM   table_all
   ) sub
WHERE (tile%10 = 0 OR tile = 5)
AND    tile <= 90
GROUP  BY 1,2,3
ORDER  BY 1,2,3;

%.. 模运算符
GROUP BY 1,2,3.. 位置参数

于 2013-06-06T23:55:38.680 回答
0

看起来您正在寻找return query execute,从动态 SQL 语句返回结果:

http://www.postgresql.org/docs/current/static/plpgsql-control-structures.html

http://www.postgresql.org/docs/current/static/plpgsql-statements.html

于 2013-06-06T21:04:14.863 回答