我想用指定的字符串替换NULL个值.然而,我只想对来自first个非NULLNULL个值进行这个替换.这意味着,如果NULL的值是第一个非NULLbefore,则保留NULL.

例如,考虑以下数据:

# | user_id | some_date  | animal  |
# |---------|------------|---------|
# | 1       | 2022-01-01 | NULL    | <~~ keep as NULL
# | 1       | 2022-01-02 | zebra   | <~~ 'zebra' is the first non-NULL value for user_id = 1
# | 1       | 2022-01-03 | lion    |
# | 1       | 2022-01-04 | NULL    | <~~ replace NULL with 'no_animal'
# | 1       | 2022-01-05 | cat     |
# | 2       | 2023-10-05 | NULL    | <~~ keep as NULL
# | 2       | 2023-10-06 | NULL    | <~~ keep as NULL
# | 2       | 2023-10-07 | dog     | <~~ 'dog' is the first non-NULL value for user_id = 2
# | 2       | 2023-10-08 | frog    |
# | 2       | 2023-10-09 | NULL    | <~~ replace NULL with 'no_animal'
# | 3       | 2024-02-03 | hamster | <~~ 'hamster' is the first non-NULL value for user_id = 3
# | 3       | 2024-02-04 | rabbit  |
# | 3       | 2024-02-05 | NULL    | <~~ replace NULL with 'no_animal'
# | 3       | 2024-02-06 | NULL    | <~~ replace NULL with 'no_animal'

所需输出应为:

# | user_id | some_date  | animal  | replaced_null |
# |---------|------------|---------|---------------|
# | 1       | 2022-01-01 | NULL    | NULL          |
# | 1       | 2022-01-02 | zebra   | zebra         |
# | 1       | 2022-01-03 | lion    | lion          |
# | 1       | 2022-01-04 | NULL    | no_animal     |
# | 1       | 2022-01-05 | cat     | cat           |
# | 2       | 2023-10-05 | NULL    | NULL          |
# | 2       | 2023-10-06 | NULL    | NULL          |
# | 2       | 2023-10-07 | dog     | dog           |
# | 2       | 2023-10-08 | frog    | frog          |
# | 2       | 2023-10-09 | NULL    | no_animal     |
# | 3       | 2024-02-03 | hamster | hamster       |
# | 3       | 2024-02-04 | rabbit  | rabbit        |
# | 3       | 2024-02-05 | NULL    | no_animal     |
# | 3       | 2024-02-06 | NULL    | no_animal     |

sql方言

我使用运行在Trino SQL上的AWS Athena.

可重现数据

WITH my_tbl AS (
    SELECT *
    FROM (VALUES
        (1, DATE '2022-01-01', NULL),
        (1, DATE '2022-01-02', 'zebra'),
        (1, DATE '2022-01-03', 'lion'),
        (1, DATE '2022-01-04', NULL),
        (1, DATE '2022-01-05', 'cat'),
        (2, DATE '2023-10-05', NULL),
        (2, DATE '2023-10-06', NULL),
        (2, DATE '2023-10-07', 'dog'),
        (2, DATE '2023-10-08', 'frog'),
        (2, DATE '2023-10-09', NULL),
        (3, DATE '2024-02-03', 'hamster'),
        (3, DATE '2024-02-04', 'rabbit'),
        (3, DATE '2024-02-05', NULL),
        (3, DATE '2024-02-06', NULL)
    ) AS t(user_id, some_date, animal)
)

推荐答案

您可以将coalesce与条件lag一起使用,忽略空值:

SELECT *,
  COALESCE(animal, 
    if(LAG(animal) ignore nulls over (PARTITION by user_id order by some_date) is not null, 'no_animal'))
    as replaced_null
FROM my_tbl
ORDER by user_id, some_date;

输出:

user_id some_date animal replaced_null
1 2022-01-01 NULL NULL
1 2022-01-02 zebra zebra
1 2022-01-03 lion lion
1 2022-01-04 NULL no_animal
1 2022-01-05 cat cat
2 2023-10-05 NULL NULL
2 2023-10-06 NULL NULL
2 2023-10-07 dog dog
2 2023-10-08 frog frog
2 2023-10-09 NULL no_animal
3 2024-02-03 hamster hamster
3 2024-02-04 rabbit rabbit
3 2024-02-05 NULL no_animal
3 2024-02-06 NULL no_animal

Sql相关问答推荐

PG SQL中按条件聚合值

Postgresql:从jsons数组到单个id索引的json

postgresql插入json不工作

为什么Prisma生成唯一索引,而不是基于方案上的唯一列约束?

将所有XML文件导入到SQL Server中

带上最后日期(结果)

在SQL Server中设置关联对象的有效JSON格式

数据库SQL-CTE命名空间(错误?)使用临时视图

从选定记录中提取摘要作为值的划分

当 ansible 变量未定义或为空时,跳过 sql.j2 模板中的 DELETE FROM 查询

SQL 将 Varchar 转换为日期

正则表达式:停在第一个匹配的其中一个字符位置上

为什么在事务中未被后续使用的CTE执行SELECT...FOR UPDATE无效?

for each 客户查找每个类别的最新评分

如何按日期和位置对最近 3 个报告日期的 SQL 查询结果进行透视?

如何更改 duckdb R 中的数据约束

在 SQL 的每行选项中 Select 最大值

交叉应用 OPENJSON / PIVOT - 错误的顺序

SQL Group By 然后映射出是否存在值

如何列出 Oracle 数据库中的所有函数并按修改日期排序