sql - 替换每个分区的 NULL 值

标签 sql postgresql null window-functions coalesce

我想使用关联的非 NULL 值填充每个 session_iddevice 列中的 NULL 值。我怎样才能实现这一目标?

这是示例数据:

+------------+-------+---------+
| session_id | step  | device  |
+------------+-------+---------+
| 351acc     | step1 |         |
| 351acc     | step2 |         |
| 351acc     | step3 | mobile  |
| 351acc     | step4 | mobile  |
| 350bca     | step1 | desktop |
| 350bca     | step2 |         |
| 350bca     | step3 |         |
| 350bca     | step4 | desktop |
+------------+-------+---------+

所需输出:

+------------+-------+---------+
| session_id | step  | device  |
+------------+-------+---------+
| 351acc     | step1 | mobile  |
| 351acc     | step2 | mobile  |
| 351acc     | step3 | mobile  |
| 351acc     | step4 | mobile  |
| 350bca     | step1 | desktop |
| 350bca     | step2 | desktop |
| 350bca     | step3 | desktop |
| 350bca     | step4 | desktop |
+------------+-------+---------+

最佳答案

window function first_value()正确的订购可能是最便宜的:

SELECT session_id, step
     , COALESCE(device
              , first_value(device) OVER (PARTITION BY session_id ORDER BY device IS NULL, step)
               ) AS device
FROM   tbl
ORDER  BY session_id DESC, step;

db<> fiddle here

ORDER BY device IS NULL,stepNULL 值排在最后,因此会选择最早具有 notnull 值的 step。请参阅:

如果每个 session_id 的 notnull 设备始终相同,您可以简化为仅 ORDER BY device IS NULL。而且您不需要COALESCE

关于sql - 替换每个分区的 NULL 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67007078/

相关文章:

sql - PostgreSQL IF 语句

postgresql - 是否可以使用数据库范围的表别名?

sql - PySpark 中的比较运算符(不等于/!=)

sql - 使用 sql - 在 select 语句中不为 null

mysql - 使用 'AND' 和 COUNT(*)

mysql - 优化 SQL 以获取行数

php - 从 MySQL 数据库填充选择字段表单数据并选择正确的值

postgresql - 为什么我的 PostgreSQL 表比它来自的 csv 更大(以 GB 为单位)?

actionscript-3 - AS 3.0引用问题

sql - 帮助优化简单的 MySQL 查询