Sql 使用group by中的rank()重写窗口函数
我有一个窗口函数,它使用rank()操作将最近的DHCP日志事件与IP地址相匹配,从而将IP与主机名相关联。问题是查询不能很好地扩展到大型数据集,因此我想尝试根据分组方式重写它,但我没有成功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(
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的澄清就无法重写。我删除的答案假设太多,有一半是不正确的。表定义和示例数据会很有帮助。