关于订单将行分组
Grouping rows into one regarding an order
我不太确定如何描述这种情况,这可能就是我很难用谷歌搜索它的原因。我什至不能说,如果这样的事情是可能的。我发现,朝着正确的方向前进的是 window functions,但是我不知道如何在这种情况下应用它。
我有一个 table 看起来像这样(加上一些与问题无关的字段):
CREATE TABLE item (marker VARCHAR(1), free TINYINT(1));
INSERT INTO item VALUES
('A', 1),
('B', 1),
('C', 0),
('D', 1),
('E', 1),
('F', 1),
('G', 0),
('H', 1),
('I', 0),
('J', 0);
我想知道如何编写查询(考虑 ORDER BY marker
)
- 按原样显示
free = 0
的所有行
- 并将所有具有
free = 1
的连续行组合成一个行,其中包含已组合行范围的信息。
所以结果可能是这样的
marker
last_marker
free
A
B
1
C
null
0
D
F
1
G
null
0
H
H
1
I
null
0
J
null
0
是的,可以用 window 函数来完成:
with cte1 as (
select *, case when free = 1 and lag(free) over (order by marker) = 1 then 0 else 1 end as grp_change
from item
), cte2 as (
select *, sum(grp_change) over (order by marker) as grp_number
from cte1
)
select min(marker), case when free = 1 then max(marker) end, free
from cte2
group by grp_number, free
它的工作原理如下:
- 标记所有具有 free = 0 或(free = 1 和前一行 free <> 1)的行
- 对标记的行进行 运行 求和以创建组编号
- 按组号对数据进行分组
我不太确定如何描述这种情况,这可能就是我很难用谷歌搜索它的原因。我什至不能说,如果这样的事情是可能的。我发现,朝着正确的方向前进的是 window functions,但是我不知道如何在这种情况下应用它。
我有一个 table 看起来像这样(加上一些与问题无关的字段):
CREATE TABLE item (marker VARCHAR(1), free TINYINT(1));
INSERT INTO item VALUES
('A', 1),
('B', 1),
('C', 0),
('D', 1),
('E', 1),
('F', 1),
('G', 0),
('H', 1),
('I', 0),
('J', 0);
我想知道如何编写查询(考虑 ORDER BY marker
)
- 按原样显示
free = 0
的所有行 - 并将所有具有
free = 1
的连续行组合成一个行,其中包含已组合行范围的信息。
所以结果可能是这样的
marker | last_marker | free |
---|---|---|
A | B | 1 |
C | null | 0 |
D | F | 1 |
G | null | 0 |
H | H | 1 |
I | null | 0 |
J | null | 0 |
是的,可以用 window 函数来完成:
with cte1 as (
select *, case when free = 1 and lag(free) over (order by marker) = 1 then 0 else 1 end as grp_change
from item
), cte2 as (
select *, sum(grp_change) over (order by marker) as grp_number
from cte1
)
select min(marker), case when free = 1 then max(marker) end, free
from cte2
group by grp_number, free
它的工作原理如下:
- 标记所有具有 free = 0 或(free = 1 和前一行 free <> 1)的行
- 对标记的行进行 运行 求和以创建组编号
- 按组号对数据进行分组