Pat*_*ick 14 sql postgresql window-functions postgresql-9.4
在PostgreSQL 9.4中,窗口函数具有a的新选项,FILTER用于选择窗口框架的子集以进行处理.文档提到了它,但没有提供样本.在线搜索会产生一些样本,包括来自2ndQuadrant的样本,但我发现的所有样本都是具有常量表达式的相当简单的例子.我要找的是一个包含当前行值的过滤器表达式.
假设我有一堆包含一堆列的表,其中一列是date类型:
col1 | col2 | dt ------------------------ 1 | a | 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 | count -------------------------------- 1 | a | 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可以在窗口框架中选择范围?框架规范没有帮助,因为它都是基于行的.
我对使用子查询的替代解决方案不感兴趣,它必须基于窗口处理.
您实际上并未聚合行,因此新的聚合FILTER子句不是正确的工具.窗口函数更像它,但问题仍然存在:窗口的帧定义不能依赖于当前行的值.它只能计算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它可能会破坏更复杂的查询.
有关:
| 归档时间: | 
 | 
| 查看次数: | 2848 次 | 
| 最近记录: |