在 PostgreSQL 中根据多个字段更改(包括 "invisible" 一个)对行进行编号
Numbering rows based on multiple fields changes (incluging an "invisible" one) in PostgreSQL
之前的题目我看了看,还是达不到我想要的
我有一个这样的 table :
id status update_date
--- --- ---
A PENDING 2020-11-01
A PENDING 2020-11-02
A CONFIRMED 2020-11-03
A CONFIRMED 2020-11-04
A CONFIRMED 2020-11-05
A PENDING 2020-11-06
A PAID 2020-11-07
B CONFIRMED 2020-11-02
etc.
我想要这个:
id status rank
--- --- ---
A PENDING 1
A CONFIRMED 2
A PENDING 3
A PAID 4
B CONFIRMED 1
etc.
意味着考虑 update_date(当然还有状态变化)对行进行排序和编号,但最终结果中没有订单日期
PS:如您所见,我可以多次从一种状态来回切换到另一种状态(PENDING -> CONFIRMED -> PENDING -> 等)
非常感谢!
您可以将此作为间隙和孤岛问题来解决。行号之间的差异为您提供了每条记录所属的组,然后您可以使用它来聚合:
select id, status,
row_number() over(partition by id order by min(update_date)) as rn
from (
select t.*,
row_number() over(partition by id order by update_date) rn1,
row_number() over(partition by id, status order by update_date) rn2
from mytable t
) t
group by id, status, rn1 - rn2
order by id, min(update_date)
id | status | rn
:- | :-------- | -:
A | PENDING | 1
A | CONFIRMED | 2
A | PENDING | 3
A | PAID | 4
B | CONFIRMED | 1
SELECT
id,
status,
row_number() OVER (PARTITION BY id) -- 3
FROM (
SELECT
*,
lead(status) OVER (PARTITION BY id ORDER BY update_date) AS next -- 1
FROM
mytable
) s
WHERE status != next OR next is null -- 2
lead()
window function 将下一个 status
值复制到当前记录
- 删除所有记录,其中当前和下一个
status
相等(状态无变化)
- 使用
row_number()
window 函数添加行计数
之前的题目我看了看,还是达不到我想要的
我有一个这样的 table :
id status update_date
--- --- ---
A PENDING 2020-11-01
A PENDING 2020-11-02
A CONFIRMED 2020-11-03
A CONFIRMED 2020-11-04
A CONFIRMED 2020-11-05
A PENDING 2020-11-06
A PAID 2020-11-07
B CONFIRMED 2020-11-02
etc.
我想要这个:
id status rank
--- --- ---
A PENDING 1
A CONFIRMED 2
A PENDING 3
A PAID 4
B CONFIRMED 1
etc.
意味着考虑 update_date(当然还有状态变化)对行进行排序和编号,但最终结果中没有订单日期
PS:如您所见,我可以多次从一种状态来回切换到另一种状态(PENDING -> CONFIRMED -> PENDING -> 等)
非常感谢!
您可以将此作为间隙和孤岛问题来解决。行号之间的差异为您提供了每条记录所属的组,然后您可以使用它来聚合:
select id, status,
row_number() over(partition by id order by min(update_date)) as rn
from (
select t.*,
row_number() over(partition by id order by update_date) rn1,
row_number() over(partition by id, status order by update_date) rn2
from mytable t
) t
group by id, status, rn1 - rn2
order by id, min(update_date)
id | status | rn :- | :-------- | -: A | PENDING | 1 A | CONFIRMED | 2 A | PENDING | 3 A | PAID | 4 B | CONFIRMED | 1
SELECT
id,
status,
row_number() OVER (PARTITION BY id) -- 3
FROM (
SELECT
*,
lead(status) OVER (PARTITION BY id ORDER BY update_date) AS next -- 1
FROM
mytable
) s
WHERE status != next OR next is null -- 2
lead()
window function 将下一个status
值复制到当前记录- 删除所有记录,其中当前和下一个
status
相等(状态无变化) - 使用
row_number()
window 函数添加行计数