使用窗口函数动态选择任意n列

问题描述 投票:1回答:1

我真实的选择陈述的摘要:

select 
  lag(somecol) over (partition by thing_id) as prev_1,
  lag(somecol,2) over (partition by thing_id) as prev_2,
  lag(somecol,3) over (partition by thing_id) as prev_3,
  othercol,
  ...

在真正的查询中,over要复杂得多,导致代码非常密集,难以理解。此外,获取最后3行是硬编码的(vs n = whatever)。

有没有办法在直接SQL中迭代或递归地指定这些prev_x列,以便1)代码更具可读性; 2)您可以动态指定prev cols的数量n?

sql postgresql
1个回答
1
投票

为了回答第一个问题,为了使代码更具可读性,Postgres允许定义窗口,为其命名,然后在查询中多次引用它。

请参阅Window Functions的文档:

当查询涉及多个窗口函数时,可以使用单独的OVER子句写出每个函数,但如果需要对多个函数使用相同的窗口行为,则这是重复且容易出错的。相反,每个窗口行为都可以在WINDOW子句中命名,然后在OVER中引用。例如:

SELECT sum(salary) OVER w, avg(salary) OVER w
FROM empsalary
WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);

我不知道这个功能是否是SQL标准的一部分,但我知道SQL Server不支持它。

所以,你的查询看起来像这样:

select 
  lag(somecol) over w as prev_1,
  lag(somecol,2) over w as prev_2,
  lag(somecol,3) over w as prev_3,
  othercol,
  ...
from
  ...
WINDOW w AS (partition by thing_id)
;

关于你的第二个问题如何“动态指定prev cols的数量n” - 你需要动态生成SELECT语句的文本来实现它。 RDBMS假设稳定的模式,即表和查询中的列数通常是固定的,而不是动态的。

© www.soinside.com 2019 - 2024. All rights reserved.