【问题标题】:Numbering rows based on multiple fields changes (incluging an "invisible" one) in PostgreSQL在 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.)

非常感谢!

【问题讨论】:

    标签: sql postgresql gaps-and-islands dense-rank


    【解决方案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
    
    1. lead() window function 将下一个 status 值复制到当前记录
    2. 删除当前和下一个status相等的所有记录(状态不变)
    3. 使用row_number()窗口函数添加行数

    【讨论】:

    • 非常感谢!我自己不会找到它
    猜你喜欢
    • 1970-01-01
    • 2020-06-04
    • 2018-03-16
    • 2019-04-10
    • 2018-04-20
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多