首页 > 解决方案 > POSTGRESQL:如果具有相同的条件,则使用相同的数字枚举

问题描述

我有的

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 。但这会导致另一种枚举。

谢谢你的帮助

标签: postgresqlpartitionrow-numberenumerate

解决方案


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

点击:demo:db<>fiddle

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

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

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


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

点击:demo:db<>fiddle

首先,用于查找每个值组first_value()的最低值:id

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

第一个值 ( foo == 1, blah == 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

推荐阅读