Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有人能解释一下这个SQL吗?(我如何将其参数化并作为函数调用?)_Sql_Postgresql_Plpgsql - Fatal编程技术网

有人能解释一下这个SQL吗?(我如何将其参数化并作为函数调用?)

有人能解释一下这个SQL吗?(我如何将其参数化并作为函数调用?),sql,postgresql,plpgsql,Sql,Postgresql,Plpgsql,我遇到了这段“voodoo”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

我遇到了这段“voodoo”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;
要点:
  • 请注意,这不是PL/pgSQL函数。您也可以使用
    语言plpgsql
    ,但这里不需要这样做

  • 我把你的巫毒核心换成了,应该是一样的,只是更简单而已

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

  • 在PostgreSQL中调用类型
    double

  • 若要返回多行,请将函数定义为
    RETURNS SETOF record
    或与我所做的一样

  • orderby
    可以使用位置参数,因此您不必再次详细说明第一列的计算:
    orderby 1

    但是,同一
    grp
    中有多行。将更多列或表达式添加到
    ORDER BY
    子句中,以获得稳定的排序顺序

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

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;
要点:
  • 请注意,这不是PL/pgSQL函数。您也可以使用
    语言plpgsql
    ,但这里不需要这样做

  • 我把你的巫毒核心换成了,应该是一样的,只是更简单而已

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

  • 在PostgreSQL中调用类型
    double

  • 若要返回多行,请将函数定义为
    RETURNS SETOF record
    或与我所做的一样

  • orderby
    可以使用位置参数,因此您不必再次详细说明第一列的计算:
    orderby 1

    但是,同一
    grp
    中有多行。将更多列或表达式添加到
    ORDER BY
    子句中,以获得稳定的排序顺序


无法单独运行子查询,因为它引用外部查询:
e.col1
。但是,整个构造是无效的,因为我们可以使用窗口函数
rank()
。我在回答中使用了它。我已重新格式化了初始查询-这可能会使其内部发生的情况更清楚一些。您不能单独运行子查询,因为它引用外部查询:
e.col1
。但是,整个构造是无效的,因为我们可以使用窗口函数
rank()
。我在回答中使用了它。我已重新格式化了初始查询-这可能会使其内部发生的事情更加清晰。+1用于指向窗口功能的链接-它打开了一个全新的世界(意料之外的双关语!)。+1用于指向窗口功能的链接-它打开了一个全新的世界(意料之外的双关语!)。