在 PostgreSQL 中基于多个字段更改(包括“不可见”)对行进行编号
Posted
技术标签:
【中文标题】在 PostgreSQL 中基于多个字段更改(包括“不可见”)对行进行编号【英文标题】:Numbering rows based on multiple fields changes (incluging an "invisible" one) in PostgreSQL 【发布时间】:2021-03-13 12:05:22 【问题描述】:我看过之前的主题,但我无法实现我想要的。
我有一张这样的桌子:
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.
意思是考虑更新日期(当然还有状态变化)来对行进行排序和编号,但最终结果中没有订单日期
PS:如你所见,我可以多次从一种状态到另一种状态(PENDING -> CONFIRMED -> PENDING -> etc.)
非常感谢!
【问题讨论】:
【参考方案1】:您可以将其作为一个空白和孤岛问题来解决。行号之间的差异为您提供每条记录所属的组,然后您可以使用它来聚合:
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)
Demo on DB Fiddle:
编号 |状态 | rn :- | :-------- | -: 一个 |待定 | 1 一个 |已确认 | 2 一个 |待定 | 3 一个 |付费 | 4 乙|已确认 | 1【讨论】:
感谢这个解决方案,但 postgresql 将以 row_number() 开头的部分变灰并返回“在“rn1”或附近出现语法错误 @jeremoquai:group by
子句中缺少逗号:已修复。
@jeremoquai:请注意,这比您接受的答案更有效,因为只有一级子查询(在接受的解决方案中为两级)。【参考方案2】:
step-by-step demo:db<>fiddle
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()
窗口函数添加行数
【讨论】:
非常感谢!我自己不会找到它以上是关于在 PostgreSQL 中基于多个字段更改(包括“不可见”)对行进行编号的主要内容,如果未能解决你的问题,请参考以下文章