在窗口函数的FILTER子句中引用当前行

帕特里克

PostgreSQL 9.4中,窗口函数具有a的新选项,FILTER可以选择要处理的窗口框架的子集。文档中提到了它,但没有提供示例。在线搜索产生了一些样本,包括来自2ndQuadrant的样本,但是我发现的所有样本都是带有常量表达式的琐碎示例。我正在寻找的是一个包含当前行值的过滤器表达式。

假设我有一个带有一堆列的表,其中之一是date类型:

col1 | col2 | dt
------------------------
  1 | 一个| 2015-07-01
  2 | b | 2015-07-03
  3 | c | 2015-07-10
  4 | d | 2015-07-11
  5 | e | 2015-07-11
  6 | f | 2015-07-13
...

date整个表的处理窗口定义很简单:WINDOW win AS (ORDER BY dt)

我想知道当前行(包括该行)之前的4天中有多少行。所以我想生成以下输出:

col1 | col2 | dt | 计数
--------------------------------
  1 | 一个| 2015-07-01 | 1个
  2 | b | 2015-07-03 | 2
  3 | c | 2015-07-10 | 1个
  4 | d | 2015-07-11 | 3
  5 | e | 2015-07-11 | 3
  6 | f | 2015-07-13 | 4
...

FILTER窗口函数子句似乎是显而易见的选择:

count(*) FILTER (WHERE current_row.dt - dt <= 4) OVER win

但是,如何指定current_row.dt(因为缺少更好的语法)?这有可能吗?

如果无法做到这一点,是否还有其他方法date可以在窗口框架中选择范围?框架规范无济于事,因为它们都是基于行的。

我对使用子查询的替代解决方案不感兴趣,它必须基于窗口处理。

欧文·布兰德斯特

您实际上不是在聚合行,因此新的gregationFILTER子句不是正确的工具。窗口函数更像它,但是问题仍然存在:窗口帧定义不能依赖于当前行的它只能计算ROWS子句之前或之后的给定行数

为了使这项工作有效,每天和整天LEFT JOIN范围内的总计计数然后,您可以应用窗口函数:

SELECT t.*, ct.ct_last4days
FROM  (
   SELECT *, sum(ct) OVER (ORDER BY dt ROWS 3 PRECEDING) AS ct_last4days
   FROM  (
      SELECT generate_series(min(dt), max(dt), interval '1 day')::date AS dt
      FROM   tbl t1
      ) d
   LEFT   JOIN (SELECT dt, count(*) AS ct FROM tbl GROUP BY 1) t USING (dt)
   ) ct
JOIN  tbl t USING (dt);

遗漏ORDER BY dt框架定义中的省略通常是可行的,因为顺序是从generate_series()子查询中继承的。但是,如果没有显式的SQL标准,就无法保证,ORDER BY它可能会在更复杂的查询中中断。

SQL提琴。

有关:

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章