【发布时间】:2012-01-04 11:14:39
【问题描述】:
我遇到了这段'voodoo' SQL,它被用来对表中的数据进行自定义分组。我想了解它是如何变魔术的,但我无法理解它。那里的 SQL 专家可以用简单的英语向不太懂 SQL 的人解释这个 sn-p 的各个部分,它可以发挥它的魔力吗?
select ceil(rnk/10.0) as grp,
col1, col2, col3, col4, col5, col6, col7
from (select e.col1, e.col2, e.col3, e.col4, e.col5, e.col6, e.col7,
(select count(*)
from mytable d
where e.col1 > d.col1)+1 as rnk
from mytable e) x
order by grp;
上面我似乎无法理解的部分 SQL 是返回列“x”的内部 SQL:
(select count(*) from mytable d
where e.col1 > d.col1)+1 as rnk
from mytable e
) x
我希望能够自行运行该查询:
select count(*) from mytable d
where e.col1 > d.col1)+1 as rnk
from mytable e
但是,当我这样做时,我得到了错误:
错误:“+”处或附近的语法错误第 2 行:其中 e.col1 > d.col1)+1 作为 rnk
那么,那里发生了什么?!
另外,当前的 SQL 是用数字 10 硬编码的。我想在它周围包装一个函数,以便能够使用 10 以外的数字调用该函数。
后端数据库是 PostgreSQL,所以函数会在 PL/pgSQL 中。这是我第一次尝试编写这样的函数 - 但是,这并不完全正确,因为我想返回指定列的多行 - 所以下面的函数需要进行一些修改,不完全确定如何:
CREATE OR REPLACE FUNCTION my_custom_grouping(in integer,
out grp integer,
out col1 double,
out col2 double,
out col3 double,
out col4 double,
out col5 double,
out col6 double,
out col7 double
)
AS $$ SELECT
ceil(rnk/$1) as grp,
col1, col2, col3, col4, col5, col6, col7
from (
select e.col1, e.col2, e.col3, e.col4, e.col5, e.col6, e.col7,
(select count(*) from mytable d
where e.col1 > d.col1)+1 as rnk
from mytable e
) x
order by grp;
$$
LANGUAGE SQL;
除了不返回多于一行的函数之外,我不确定这是否是参数化查询的最佳方法 - 我在正确的路径上吗? - 如果是,我将如何修改上面的函数以返回多行而不是当前的单个“行”(即“多列”输出)?
这是对函数返回的数据运行聚合函数(按“grp”分组)的正确方法吗?
【问题讨论】:
-
您不能单独运行子查询,因为它引用了外部查询:
e.col1。然而,整个构造是无效的,因为我们可以为此使用窗口函数rank()。我在回答中使用了它。 -
我已重新格式化初始查询 - 这可能会使其中发生的事情更加清晰。
标签: sql postgresql plpgsql