使用自定义顺序区分列

Distinct on column using custom order

我有数据库视图。

此时 returns 行在 id 列中可以有重复条目。 我想执行以下操作:

SELECT DISTINCT ON (id) USING DESCRIBED BELOW RULE -- of course it is not valid sql
  id
  type

type 列可以有 3 个值:

如果有相同id但不同type的行,则DISTINCT的规则如下:

所以如果我有 3 行:

id    type
1     'y'
1     'x'
2     'z'

预期结果将是

id    type
1     'x'
2     'z'

有办法实现吗?

如果您的值实际上是按字母顺序排列的(如您的示例所示),那将非常简单 - 您只需对值进行排序:

SELECT DISTINCT ON (id)
    id,
    type
FROM mytable m
ORDER BY id, type

demo:db<>fiddle

如果没有,您将需要 table 存储排名值及其排名顺序。或者你像我一样用子查询模拟它:

SELECT DISTINCT ON (id)
    id,
    type
FROM mytable m
JOIN (VALUES (1, 'x'), (2, 'y'), (3, 'z')) AS r (rank_id,value)
ON r.value = m.type
ORDER BY id, r.rank_id

如果您的类型数据确实是固定的,您可以考虑 enum type 默认情况下是有序类型。查询看起来像上面的第一个:

demo: db<>fiddle

但请注意,更改枚举(添加、删除、重新排列值)可能非常困难。所以只有在类型确实固定的情况下才推荐使用。否则,使用带外键的单独 table 将带您回到第二部分。

您可以将层次结构放在 ORDER BY

中的 CASE 表达式中
SELECT DISTINCT ON (id) * 
FROM   ( VALUES (1, 'y'), 
                (1, 'x'), 
                (2, 'z') ) s(id, type) 
ORDER  BY id, 
          CASE type 
            WHEN 'x' THEN 1 
            WHEN 'y' THEN 2 
            WHEN 'z' THEN 3 
          END; 

Demo