自定义窗口函数忽略 Postgres 中的空值

Posted

技术标签:

【中文标题】自定义窗口函数忽略 Postgres 中的空值【英文标题】:Custom window function ignoring nulls in Postgres 【发布时间】:2020-06-05 17:58:32 【问题描述】:

Postgres 中的表格如下所示:

timestamp           | a  | b
--------------------+----+---------------------
2016-01-01 00:00:00 | 1  | 10
2016-01-01 00:00:01 | 2  | 11
2016-01-01 00:00:02 | 3  | 
2016-01-01 00:00:03 | 4  | 12
2016-01-01 00:00:04 | 5  |  
2016-01-01 00:00:05 | 6  |  
2016-01-01 00:00:06 | 7  |  
2016-01-01 00:00:07 | 8  |  
2016-01-01 00:00:08 | 9  |  
2016-01-01 00:00:09 | 10 | 13
2016-01-01 00:00:10 | 11 |  
2016-01-01 00:00:11 | 12 |  
2016-01-01 00:00:12 | 13 | 14

我想在查询中访问几个以前的非空值。假设我有以下伪查询:

SELECT timestamp,
   a,
   b,
   2 * (LAG(b, 1) IGNORE NULLS OVER (ORDER BY timestamp)) + 
   3 * (LAG(b, 2) IGNORE NULLS OVER (ORDER BY timestamp)) as calc
FROM   tbl;

这将获得以下检索结果:

timestamp           | a  | b   | calc
--------------------+----+-----+---------------
2016-01-01 00:00:00 | 1  | 10  | 
2016-01-01 00:00:01 | 2  | 11  | 
2016-01-01 00:00:02 | 3  |     | 52    (2*11 + 3*10)
2016-01-01 00:00:03 | 4  | 12  | 52    (2*11 + 3*10)
2016-01-01 00:00:04 | 5  |     | 57    (2*12 + 3*11)
2016-01-01 00:00:05 | 6  |     | 57    (2*12 + 3*11)    
2016-01-01 00:00:06 | 7  |     | 57    (2*12 + 3*11)    
2016-01-01 00:00:07 | 8  |     | 57    (2*12 + 3*11)    
2016-01-01 00:00:08 | 9  |     | 57    (2*12 + 3*11)    
2016-01-01 00:00:09 | 10 | 13  | 57    (2*12 + 3*11)
2016-01-01 00:00:10 | 11 |     | 62    (2*13 + 3*12)    
2016-01-01 00:00:11 | 12 |     | 62    (2*13 + 3*12)        
2016-01-01 00:00:12 | 13 | 14  | 62    (2*13 + 3*12) 

谢谢

【问题讨论】:

【参考方案1】:

横向连接是一种可能性:

select t.*, (t1.b * 2 + t2.b * 3)
from t left join lateral
     (select t1.*
      from t t1
      where t1.b is not null and t1.a < t.a
      order by t1.a desc
      limit 1
     ) t1 
     on true left join lateral
     (select t2.*
      from t t2
      where t2.b is not null and t2.a < t1.a
      order by t2.a desc
      limit 1
     ) t2
     on true;

Here 是一个 dbfiddle。

【讨论】:

以上是关于自定义窗口函数忽略 Postgres 中的空值的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL 查询中过滤掉由窗口函数 lag() 产生的空值

如何定义一个维度,以便在显示所有值时不忽略 FK 中的空值?

IntegrityError:postgres 从转储恢复后,所有具有 ForeignKey 的模型/字段的“id”列中的空值

带窗口的自定义Greenplum聚合函数

将列分组为一行,忽略 postgreSQL 中的空值

在带有 postgres 数据库的 jbpm 6.5.0Final 中出现错误:“id”列中的空值违反了非空约束