繁体   English   中英

有人可以解释这个SQL吗? (以及如何“参数化”它并作为函数调用?)

[英]Can someone explain this SQL? (and how may I 'parametrize' it and invoke as a function?)

我遇到了这段“ voodoo” SQL,该SQL被用来执行来自表的数据的自定义分组。 我想了解它是如何做到魔术的,但是我无法理解它。 那里的SQL专家可以用简单的英语向不懂SQL的人解释此代码段的各个部分,从而使它发挥作用吗?

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”分组)的正确方法吗?

您的(简体!)函数可能如下所示:

CREATE OR REPLACE FUNCTION my_custom_grouping(integer)
RETURNS TABLE (
   grp integer,
   col1 double precision,
   col2 double precision,
   col3 double precision,
   col4 double precision,
   col5 double precision,
   col6 double precision,
   col7 double precision) AS
$BODY$
    SELECT ceil(rank() OVER (ORDER BY col1) / $1)::int as grp
          ,col1, col2, col3, col4, col5, col6, col7
    FROM   mytable 
    ORDER  BY 1;
$BODY$ LANGUAGE SQL;

要点:

  • 请注意,这是language SQL ,不是PL / pgSQL函数。 您也可以使用language plpgsql ,但这不是必需的。

  • 我用窗口函数rank()替换了巫毒教的核心,它应该完全一样,只是更简单。

  • 我还完全删除了子查询。 没有必要。

  • 该型double被称为double precision PostgreSQL中。

  • 要返回多行,请像我一样将函数定义为RETURNS SETOF recordRETURNS TABLE

  • ORDER BY可以使用位置参数,因此您不必再次拼出第一列的计算: ORDER BY 1
    但是,同一grp有多行。 将更多列或表达式添加到ORDER BY子句中,以获得稳定的排序顺序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM