如何忽略 PostgreSQL 窗口函数中的空值?或返回列中的下一个非空值
Posted
技术标签:
【中文标题】如何忽略 PostgreSQL 窗口函数中的空值?或返回列中的下一个非空值【英文标题】:How to ignore nulls in PostgreSQL window functions? or return the next non-null value in a column 【发布时间】:2016-05-26 21:01:35 【问题描述】:假设我有下表:
| User_id | COL1 | COL2 |
+---------+----------+------+
| 1 | | 1 |
| 1 | | 2 |
| 1 | 2421 | |
| 1 | | 1 |
| 1 | 3542 | |
| 2 | | 1 |
我需要另一列来指示每一行的下一个非空 COL1 值,因此结果如下所示:
| User_id | COL1 | COL2 | COL3 |
+---------+----------+------+------
| 1 | | 1 | 2421 |
| 1 | | 2 | 2421 |
| 1 | 2421 | | |
| 1 | | 1 | 3542 |
| 1 | 3542 | | |
| 2 | | 1 | |
SELECT
first_value(COL1 ignore nulls) over (partition by user_id order by COL2 rows unbounded following)
FROM table;
可以,但我使用的是不支持忽略 null 子句的 PostgreSQL。
有什么建议的解决方法吗?
【问题讨论】:
您需要一列来指定排序。 SQL 表本质上是无序的。 【参考方案1】:如果您在订单中添加条件时,您仍然可以使用窗口功能执行此操作,如下所示:
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
这将首先使用非空值。
但是,与跳过空值相比,性能可能不会很好,因为数据库必须根据其他条件进行排序。
【讨论】:
但这与IGNORE NULLS
子句并不完全一样。
一个postgresql不支持atm的子句【参考方案2】:
我也遇到了同样的问题。其他解决方案可能有效,但我必须为我需要的每一行构建多个窗口。
你可以试试这个 sn-ps:https://wiki.postgresql.org/wiki/First/last_(aggregate)
如果您创建聚合,您可以使用它们:
SELECT
first(COL1) over (partition by user_id order by COL2 rows unbounded following)
FROM table;
【讨论】:
【参考方案3】:总是有使用相关子查询的行之有效的方法:
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;
【讨论】:
运行此程序时未找到 t2.id >= t.id 过滤器中的 t.id @user3558238 。 . .找不到是什么意思?t
是外查询中表的别名; t2
是内部查询中的别名。
是说t.user_id不存在,可能是PostgreSQL中子查询不能引用外部查询参数?
@user3558238 。 . . Postgres 绝对支持相关子查询。您应该编辑您的问题并包括您的尝试。【参考方案4】:
希望这会有所帮助,
SELECT * FROM TABLE ORDER BY COALESCE(colA, colB);
按 colA 排序,如果 colA 的值为 NULL,则按 colB 排序。
【讨论】:
【参考方案5】:您可以使用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 |
【讨论】:
以上是关于如何忽略 PostgreSQL 窗口函数中的空值?或返回列中的下一个非空值的主要内容,如果未能解决你的问题,请参考以下文章
如何定义一个维度,以便在显示所有值时不忽略 FK 中的空值?
“‘密码’的空值”——DataGrip 中的 PostgreSQL