从下表中,我尝试创建另一列 (
last_k2X
),它将显示 last key2,其中 type
随着时间的推移设置为 'X'
(ti
)。
如果同时 (
X
) 为多个 ts
设置了 key2
(在同一个 key1
分区中),则新列 last_k2X
将为所有 key2
提供 key2
那个分区/时间。
输入:
键1 | 键2 | ts | 类型 |
---|---|---|---|
1 | A | t0 | |
1 | B | t1 | a |
1 | C | t1 | X |
1 | D | t2 | b |
1 | E | t3 | |
1 | F | t4 | c |
1 | G | t5 | X |
1 | H | t5 | |
1 | 我 | t6 | d |
我尝试使用 FIRST_VALUE() 和 LAG() 等窗口函数,但无法获得正确的结果。 我期望的结果是这样的:
预期输出:
键1 | 键2 | ts | 类型 | 最后_k2X |
---|---|---|---|---|
1 | A | t0 | ||
1 | B | t1 | a | C |
1 | C | t1 | X | C |
1 | D | t2 | b | C |
1 | E | t3 | C | |
1 | F | t4 | c | C |
1 | G | t5 | X | G |
1 | H | t5 | G | |
1 | 我 | t6 | d | G |
由于您没有指定您使用的数据库系统,该解决方案是在MySQL中,但可以简单地转换到其他数据库,因为MySQL使用反引号作为转义字符。
这基本上是一个间隙和孤岛问题,但需要获得正确的分区
CREATE TABLE data
(`key1` int, `key2` varchar(1), `ts` varchar(2), `type` varchar(4))
;
INSERT INTO data
(`key1`, `key2`, `ts`, `type`)
VALUES
(1, 'A', 't0', NULL),
(1, 'B', 't1', 'a'),
(1, 'C', 't1', 'X'),
(1, 'D', 't2', 'b'),
(1, 'E', 't3', NULL),
(1, 'F', 't4', 'c'),
(1, 'G', 't5', 'X'),
(1, 'H', 't5', NULL),
(1, 'I', 't6', 'd')
;
WITH x_sel AS (SELECT `key1`, `key2`, `ts`,`type`, CASE WHEN `type` = 'X' then 1 ELSE 0 END rk
FROM data
), CTE2 as
(SELECT
x_sel.`key1`, x_sel.`key2`, x_sel.`ts`,x_sel.`type`,x_sel2.`key2` k2X, SUM(rk) OVER (PARTITION BY x_sel.`key1` ORDER BY x_sel.`key2`) s_rk FROM x_sel
LEFT JOIN (SELECT `key1`, `key2`, `ts` FROM data WHERE `type` = 'X') x_sel2
ON x_sel.`key1` = x_sel2.`key1` ANd x_sel.`ts` = x_sel2.`ts`)
SELECT `key1`, `key2`, `ts`,`type`,CASE WHEN s_rk = 0 THEn k2x ELSE COALESCE(k2x,MAX(k2X) OVER(PARTITION BY s_rk ORDER BY S_rk)) END k2x
FROM CTE2
键1 | 键2 | ts | 类型 | k2x |
---|---|---|---|---|
1 | A | t0 | 空 | 空 |
1 | B | t1 | a | C |
1 | C | t1 | X | C |
1 | D | t2 | b | C |
1 | E | t3 | 空 | C |
1 | F | t4 | c | C |
1 | G | t5 | X | G |
1 | H | t5 | 空 | G |
1 | 我 | t6 | d | G |