如何在PostgreSQL窗口函数中忽略空值?或返回列中的下一个非空值

70gysomp  于 2022-11-04  发布在  PostgreSQL
关注(0)|答案(5)|浏览(316)

假设我有下面的表:

| User_id |   COL1   | COL2 |
 +---------+----------+------+
 | 1       |          | 1    |
 | 1       |          | 2    | 
 | 1       |   2421   |      | 
 | 1       |          | 1    | 
 | 1       |   3542   |      | 
 | 2       |          | 1    |

我需要另一个列来指示每行的下一个非空COL1值,因此结果将如下所示:
第一个
可以工作,但我使用的PostgreSQL不支持忽略空值子句。
是否有建议的解决方法?

sy5wg1nm

sy5wg1nm1#

如果您按如下顺序添加case when条件,您仍然可以使用窗口函数执行此操作:

select
   first_value(COL1) 
   over (
     partition by user_id 
     order by case when COL1 is not null then 0 else 1 end ASC, COL2 
     rows unbounded following
   ) 
from table

这将首先使用非空值。
但是,与skip nulls相比,性能可能不会很好,因为数据库将不得不根据其他条件进行排序。

6uxekuva

6uxekuva2#

我也遇到了同样的问题。其他的解决方案可能会起作用,但我必须为我需要的每一行构建多个窗口。
你可以试试这个片段:https://wiki.postgresql.org/wiki/First/last_(aggregate)
如果创建了聚合,则可以使用它们:

SELECT 
first(COL1) over (partition by user_id order by COL2 rows unbounded following) 
FROM table;
ztmd8pv5

ztmd8pv53#

使用相关子查询总是一种行之有效的方法:

select t.*,
       (select t2.col1
        from t t2
        where t2.id >= t.id and t2.col1 is not null
        order by t2.id desc
        fetch first 1 row only
       ) as nextcol1
from t;
n53p2ov0

n53p2ov04#

希望这能有所帮助,

SELECT * FROM TABLE ORDER BY COALESCE(colA, colB);

它按colA排序,如果colA具有NULL值,则按colB排序。

5uzkadbs

5uzkadbs5#

您可以使用COALESCE()函数。对于您的查询:

SELECT 
first_value(COALESCE(COL1)) over (partition by user_id order by COL2 rows unbounded following) 
FROM table;

但我不明白为什么要按COL2排序,因为这几行的COL2值为空:

| User_id |   COL1   | COL2 |
 +---------+----------+------+
 | 1       |          | 1    |
 | 1       |          | 2    | 
 | 1       |   2421   |      | <<--- null?
 | 1       |          | 1    | 
 | 1       |   3542   |      | <<--- null?
 | 2       |          | 1    |

相关问题