【问题标题】:Postgresql - increment counter in rows where a column has duplicate valuePostgresql - 在列具有重复值的行中增加计数器
【发布时间】:2018-03-23 18:01:29
【问题描述】:

我在用于调度的表中添加了一个列 (seq),以便前端可以管理每个项目的显示顺序。是否可以制作一个 SQL 查询来根据日期列中的常见重复值使用增量计数器填充此列?

之前

------------------------------------
| name | date_time           | seq |
------------------------------------
| ABC1 | 15-01-2017 11:00:00 |     |
| ABC2 | 16-01-2017 11:30:00 |     |
| ABC1 | 16-01-2017 11:30:00 |     |
| ABC3 | 17-01-2017 10:00:00 |     |
| ABC3 | 18-01-2017 12:30:00 |     |
| ABC4 | 18-01-2017 12:30:00 |     |
| ABC1 | 18-01-2017 12:30:00 |     |
------------------------------------  

之后

------------------------------------
| name | date_time           | seq |
------------------------------------
| ABC1 | 15-01-2017 11:00:00 | 0   |
| ABC2 | 16-01-2017 11:30:00 | 0   |
| ABC1 | 16-01-2017 11:30:00 | 1   |
| ABC3 | 17-01-2017 10:00:00 | 0   |
| ABC3 | 18-01-2017 12:30:00 | 0   |
| ABC4 | 18-01-2017 12:30:00 | 1   |
| ABC1 | 18-01-2017 12:30:00 | 2   |
------------------------------------

已解决,感谢两个答案。 为了让任何发现这个的人更容易,工作代码是:

UPDATE my_table f
    SET seq = seq2
    FROM (
        SELECT ctid, ROW_NUMBER() OVER (PARTITION BY date_time ORDER BY ctid) -1 AS seq2
        FROM my_table
        ) s
    WHERE f.ctid = s.ctid;

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    使用window functionrow_number()

    with my_table (name, date_time) as (
    values
    
    ('ABC1', '15-01-2017 11:00:00'),
    ('ABC2', '16-01-2017 11:30:00'),
    ('ABC1', '16-01-2017 11:30:00'),
    ('ABC3', '17-01-2017 10:00:00'),
    ('ABC3', '18-01-2017 12:30:00'),
    ('ABC4', '18-01-2017 12:30:00'),
    ('ABC1', '18-01-2017 12:30:00')
    )
    
    select *, 
        row_number() over (partition by name order by date_time)- 1 as seq
    from my_table
    order by date_time;
    
     name |      date_time      | seq 
    ------+---------------------+-----
     ABC1 | 15-01-2017 11:00:00 |   0
     ABC1 | 16-01-2017 11:30:00 |   1
     ABC2 | 16-01-2017 11:30:00 |   0
     ABC3 | 17-01-2017 10:00:00 |   0
     ABC1 | 18-01-2017 12:30:00 |   2
     ABC3 | 18-01-2017 12:30:00 |   1
     ABC4 | 18-01-2017 12:30:00 |   0
    (7 rows)
    

    阅读this answer 了解有关使用唯一整数更新现有记录的类似问题。

    【讨论】:

    • 这提供了数字,我如何用这些数字更新表格?
    • 当值不重复(即相反的情况)时如何增加计数器?
    • @igorkf - 请用示例数据和预期输出提出一个新问题。
    【解决方案2】:

    查看ROW_NUMBER()

    SELECT name, date_time, ROW_NUMBER() OVER (PARTITION BY date_time ORDER BY name) FROM [table]
    

    【讨论】:

    • 很好地显示了数字,但它没有填充新列。
    • 这将返回以下错误:错误:关系“t”不存在第 1 行:UPDATE t set seq = seq2 FROM (
    • 原来我的 UPDATE 语句在 PostGres 中不起作用(但它在 SQL Server 中起作用)。你的表需要一个主键来更新,或者你可以做类似stackoverflow.com/a/6578705/1933308
    • 谢谢,我按照klin提供的链接使用了ctid
    猜你喜欢
    • 2020-04-02
    • 2021-10-23
    • 1970-01-01
    • 2019-07-12
    • 2018-09-05
    • 2017-04-30
    • 2020-02-03
    • 1970-01-01
    相关资源
    最近更新 更多