Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.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 使用group by中的rank()重写窗口函数_Sql_Postgresql_Group By - Fatal编程技术网

Sql 使用group by中的rank()重写窗口函数

Sql 使用group by中的rank()重写窗口函数,sql,postgresql,group-by,Sql,Postgresql,Group By,我有一个窗口函数,它使用rank()操作将最近的DHCP日志事件与IP地址相匹配,从而将IP与主机名相关联。问题是查询不能很好地扩展到大型数据集,因此我想尝试根据分组方式重写它,但我没有成功 create table large_table as select column1, column2, column3, column4, column5, column6 from ( select a.column1, a.column2, a.start_time, rank(

我有一个窗口函数,它使用rank()操作将最近的DHCP日志事件与IP地址相匹配,从而将IP与主机名相关联。问题是查询不能很好地扩展到大型数据集,因此我想尝试根据分组方式重写它,但我没有成功

create table large_table as
select column1, column2, column3, column4, column5, column6
from
(
  select 
    a.column1, a.column2, a.start_time,
    rank() OVER( 
      PARTITION BY a.column2, a.column1 order by a.start_time DESC 
    ) as rank,
    last_value( a.column3) OVER (
      PARTITION BY a.column2, a.column1 order by a.start_time ASC
      RANGE BETWEEN unbounded preceding and unbounded following 
    ) as column3,
    a.column4, a.column5, a.column6
  from 
    (table2 s 
      INNER JOIN table3 t 
      ON s.column2=t.column2 and s.event_time > t.start_time 
    ) a
 ) b
 where rank =1;
问题1: 如何使用GROUPBY而不是窗口函数重写上述查询


我不认为以这种方式编写windows group by是一种成功的策略。当您将聚合从一个表连接回主表时,这将导致严重的性能问题

更好的方法是使用plpgsql和在循环中添加窗口信息的函数。例如,可以按如下方式添加rownumber:

CREATE OR REPLACE FUNCTION foo_with_rownumber () RETURNS SETOF foo_with_rownumber
LANGUAGE PLPGSQL AS $$
DECLARE out_val foo_with_rownumber;
        iter int;
BEGIN
    iter := 1;
    FOR out_val IN select f.*, 0 FROM foo order by bar
    LOOP
        out_val.rownumber = iter;
        return next out_val;
        iter := iter + 1;
    END LOOP;
END;
$$;

添加rank()只需稍微复杂一点,这样您就可以开始了。

该查询是否必须与输出完全匹配?您能否为表和列提供一些有意义的名称,以便我们更好地理解这个问题。您需要为
table2
table3
提供表定义列的来源隐藏在子查询
a
@ErwinBrandstetter:您的尝试看起来很合理(briljant反向工程),但似乎缺少滞后(1)结果。@wildplasser:我在
last\u value()
表达式上遇到了问题。“最后一个值”不是由排序依据定义的。它产生任意的、特定于实现的结果。原来的查询实际上被破坏了,没有OP的澄清就无法重写。我删除的答案假设太多,有一半是不正确的。表定义和示例数据会很有帮助。