提问人:Senthil 提问时间:11/17/2023 最后编辑:Simeon PilgrimSenthil 更新时间:11/17/2023 访问量:23
我想为两行之间的记录添加一个标志列
I want to add a flag column for records between two rows
问:
我有一张如下表。在此表中,我想使用标志标记每个 ID 的第一个目的 A(包括第一个目的 A 行)和第二个目的 A 之间的所有行。
编号 | 目的 | 会期 |
---|---|---|
1 | 一个 | 1KK秒 |
1 | B | 2SSK公司 |
1 | B | 3PFK的 |
1 | 一个 | 4LSK系列 |
1 | B | 5kwk |
2 | 一个 | 1kll |
2 | B | 2毫升 |
2 | 一个 | 4FNH系列 |
2 | B | 5分 |
期望如下。因此,第二个目的 A 之前的所有行都会针对每个不同的 ID 进行标记。
编号 | 目的 | 会期 | 旗 |
---|---|---|---|
1 | 一个 | 1KK秒 | 1 |
1 | B | 2SSK公司 | 1 |
1 | B | 3PFK的 | 1 |
1 | 一个 | 4LSK系列 | 0 |
1 | B | 5kwk | 0 |
2 | 一个 | 1kll | 1 |
2 | B | 2毫升 | 1 |
2 | 一个 | 4FNH系列 | 0 |
2 | B | 5分 | 0 |
可以让我知道我们如何实现这一目标,
答:
1赞
Simeon Pilgrim
11/17/2023
#1
因此,假设会话中有一个为您的数据提供订单的字段(正如我看到的 1、2、3、4、5),否则正如 NickW 所指出的那样,您的数据中没有实际的顺序。
我们可以从 CTE 开始,为我们提供您的启动状态:
with fake_data(id, purpose, session) as (
select * from values
(1, 'A', '1kks'),
(1, 'B', '2ssk'),
(1, 'B', '3pfk'),
(1, 'A', '4lsk'),
(1, 'B', '5kwk'),
(2, 'A', '1kll'),
(2, 'B', '2mlk'),
(2, 'A', '4fnh'),
(2, 'B', '5pts')
)
select *
from fake_data
order by 1,3;
因此,您希望 from 并包括第一个 until 并且不包括第二个/稍后,因此我们要注释 A 的存在,然后对每个看到的值求和,并标记/匹配第一批。A
A
A
因此,有了更多的数据,以及这个逻辑:
with fake_data(id, purpose, session) as (
select * from values
(1, 'A', '1kks'),
(1, 'B', '2ssk'),
(1, 'B', '3pfk'),
(1, 'A', '4lsk'),
(1, 'B', '5kwk'),
(2, 'A', '1kll'),
(2, 'B', '2mlk'),
(2, 'A', '4fnh'),
(2, 'B', '5pts'),
(3, 'B', '1kll'),
(3, 'A', '2mlk'),
(3, 'B', '4fnh'),
(3, 'A', '5pts')
)
select *
,purpose = 'A' as is_a
,sum(is_a::int) over (partition by id order by session) as sum_of_a
,sum_of_a = 1 as flag
from fake_data
order by 1,3;
可以像这样全部捣碎在一起:
select *
,sum((purpose = 'A')::int) over (partition by id order by session) = 1 as flag
from fake_data
order by 1,3;
所以它是如何工作的,首先我们检查是一个,然后我们将这个 BOOLEAN 转换为与 相同的 INT(IFF 是内联 IF 命令),然后我们使用 SUM 的窗口函数形式对这个值链求和,然后我们检查值 1 的存在,因为我们只想要第一个集合, 如增强数据所示,它适用于忽略 also 之前的前缀数据。purpose
A
IFF(is_a, 1, 0)
A
评论