Cod*_*tie 5 postgresql window-functions
我正在尝试使用按日期排序的组中的NULL先前值填充多个列(不同列类型 INT、VARCHAR)中的值。NOT NULL考虑下表:
CREATE TABLE IF NOT EXISTS test (
id VARCHAR,
date DATE,
value_1 INT,
value_2 VARCHAR
);
INSERT INTO test VALUES
(1, '2022-01-04', 5, 'asdf'),
(1, '2022-01-03', NULL, NULL),
(1, '2022-01-02', NULL, 'def'),
(1, '2022-01-01', 4, NULL),
(2, '2022-01-04', 1, 'a'),
(2, '2022-01-03', NULL, NULL),
(2, '2022-01-02', 2, 'b'),
(2, '2022-01-01', NULL, NULL);
Run Code Online (Sandbox Code Playgroud)
我想到达这里(请考虑 value_1 --> INTEGER、value_2 字符串):
有一天,PostgreSQL 可能会支持和函数IGNORE NULLS的选项。LEADLAG
同时,您必须使用窗口函数来构建组,然后选择每个组中的最大值。
SELECT id, date,
MAX(value_1) OVER (PARTITION BY id, grp_1) AS value_1,
MAX(value_2) OVER (PARTITION BY id, grp_2) AS value_2
FROM(
SELECT *,
COUNT(value_1) OVER (PARTITION BY id ORDER BY Date DESC) as grp_1,
COUNT(value_2) OVER (PARTITION BY id ORDER BY Date DESC) as grp_2
FROM test
) T
ORDER BY ID, date
Run Code Online (Sandbox Code Playgroud)
解释:
COUNT(value_1) OVER (PARTITION BY id ORDER BY Date ASC/DESC)是一个累积计数,仅在value_1不为空时增加。结果是,对于它采用的每个连续值(1、2、3),将有 1 条记录value_1不为空,以及 0、1 条或多条记录该字段为空。
例子:
ORDER BY Date窗口中指定的记录);value_1 is null=>count为 0。value_1 is not null=>count为 1。value_1 is null=>count保持在 1。value_1 is null=>count保持在 1。value_1 is not null=>count是 2. 使用此模式,MAX(value_1) OVER (PARTITION BY id, grp_1)通过从每个组中取出非空值来处理此记录分区。
[count = 0]只有 1 条记录null=>max为空。[count = 1]有 1 个非空值和 2 个空值 => 这max是非空值。[count = 2]有 1 个非空值(以及未指定数量的空值) => 这max是非空值。这种模式一直持续下去;对于 的每个值count(除了0),max窗口函数始终恰好有 1 个非空值可供选择。
编辑:
上面的查询是问题原始版本的答案。现在日期已更改为与以前完全相反的顺序,因此 3 次出现的位置ORDER BY date必须全部颠倒以匹配。基本上,2 个负数就是一个正数。
SELECT id, date,
MAX(value_1) OVER (PARTITION BY id, grp_1) AS value_1,
MAX(value_2) OVER (PARTITION BY id, grp_2) AS value_2
FROM(
SELECT *,
COUNT(value_1) OVER (PARTITION BY id ORDER BY Date ASC) as grp_1,
COUNT(value_2) OVER (PARTITION BY id ORDER BY Date ASC) as grp_2
FROM test
) T
ORDER BY ID, date DESC
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1037 次 |
| 最近记录: |