sql - 在稀疏表中选择一行第一个非空值

标签 sql postgresql null window-functions

使用下表:

A | B    | C    | ts
--+------+------+------------------
1 | null | null | 2016-06-15 10:00
4 | null | null | 2016-06-15 11:00 
4 |    9 | null | 2016-06-15 12:00
5 |    1 |    7 | 2016-06-15 13:00

如何在 N 行的运行窗口中选择每列的第一个非空值? “第一个”由 ts 列中的时间戳顺序定义。查询上表将导致:

A | B | C
--+---+---
1 | 9 | 7

最佳答案

窗口函数first_value()允许一个相当简短和优雅的解决方案:

SELECT first_value(a) OVER (ORDER BY a IS NULL, ts) AS a
     , first_value(b) OVER (ORDER BY b IS NULL, ts) AS b
     , first_value(c) OVER (ORDER BY c IS NULL, ts) AS c
FROM   t
LIMIT  1;

a IS NULL 的计算结果为 TRUEFALSEFALSE 排在 TRUE 之前。这样,非空值排在第一位。接下来按 ts(您评论的时间戳列)排序,然后您就可以在一个 SELECT 中得到它。

如果 Postgres 支持 IGNORE NULLS,这会更简单。 The manual:

The SQL standard defines a RESPECT NULLS or IGNORE NULLS option for lead, lag, first_value, last_value, and nth_value. This is not implemented in PostgreSQL: the behavior is always the same as the standard's default, namely RESPECT NULLS.

该领域中关于标准 SQL 的少数遗漏之一。

我们也不能使用 FILTER 子句。见:

The manual:

Only window functions that are aggregates accept a FILTER clause.

db<> fiddle here
<子>旧sqlfiddle

关于sql - 在稀疏表中选择一行第一个非空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20739117/

相关文章:

sql - 在 Oracle 中的 BEFORE INSERT TRIGGER 中何时不需要 FOR EACH ROW?

android - 为什么定位应用程序崩溃

java - 弗洛伊德算法 : Array Null Pointer Exception

mysql - 如何使用sql查询将列引入行?

mysql - SQL INTERVAL 不适用于 openshift

sql - 在您 SQL Server 职业生涯的某个阶段,参数嗅探是否会突然跳出来并发起攻击?

java - org.postgresql.util.PSQLException : The column index is out of range: 3, 列数:2

postgresql - 亚马逊免费套餐与 Heroku 付费套餐

java - 如何在 Web 应用程序中将此 .java 文件作为单独的 Java 应用程序运行以测试它?

c# - 抽象基类/派生类的空合并问题