SQL 根据另一列的顺序和值获取组中的最后一列

问题描述 投票:0回答:1

从下表中,我尝试创建另一列 (

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
sql window-functions partition-by exasol first-value
1个回答
0
投票

由于您没有指定您使用的数据库系统,该解决方案是在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

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.