【问题标题】:POSTGRESQL: Enumerate with the same number if having the same criteriaPOSTGRESQL:如果具有相同的条件,则使用相同的数字枚举
【发布时间】:2020-05-08 08:56:25
【问题描述】:

我有什么

id | value
1 | foo
2 | foo
3 | bah
4 | bah
5 | bah
6 | jezz
7 | jezz
8 | jezz
9 | pas
10 | log

我需要什么: 枚举行,如下例所示

id | value | enumeration
1 | foo | 1
2 | foo | 1
3 | bah | 2
4 | bah | 2
5 | bah | 2
6 | jezz | 3
7 | jezz | 3
8 | jezz | 3
9 | pas | 4
10 | log | 5

我已经尝试过分区的 row_number。但这会导致另一种枚举。

感谢您的帮助

【问题讨论】:

    标签: postgresql partition row-number enumerate


    【解决方案1】:

    对于这种情况,您可以使用 rank()dense_rank()

    Click: demo:db<>fiddle

    SELECT
        *,
        dense_rank() OVER (ORDER BY value)
    FROM
        mytable
    

    rank() 为组中的每个元素生成一个有序数字,但它会产生间隙(如果第一组中有 3 个元素,则从第 4 行开始的第二组将获得数字 4)。 dense_rank() 避免了这些差距。

    注意,这将按value 列按字母顺序对表格进行排序。因此,结果将是:blah == 1foo == 2jezz == 3log == 4pas == 5


    如果您想保留您的订单,您需要一个额外的订单标准。在您的情况下,您可以使用 id 列来创建这样一个列,如果没有其他可用:

    Click: demo:db<>fiddle

    首先,使用first_value() 找到每个值组中最低的id

    SELECT
        *,
        first_value(id) OVER (PARTITION BY value ORDER BY id)
    FROM
        mytable
    

    第一个值(foo == 1blah == 3、...)可用于在计算dense_rank()时保持原始顺序:

    SELECT
        id,
        value,
        dense_rank() OVER (ORDER BY first_value)
    FROM (
        SELECT
           *,
           first_value(id) OVER (PARTITION BY value ORDER BY id)
        FROM
           mytable
    ) s
    

    【讨论】:

    • 非常感谢 :-) 这正是我所需要的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 2019-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多