0

我有一个数据库视图。

此时,它返回列中可以有重复条目的id行。我想做以下事情:

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

type列可以有 3 个值:

  • x
  • y
  • z

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

  • x首先选择具有类型的行
  • y如果没有,则选择带有类型的行x
  • z如果没有x和否,则选择带有类型的行y

所以如果我有 3 行:

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

预期的结果将是

id    type
1     'x'
2     'z'

有没有办法做到这一点?

4

2 回答 2

1

您可以将层次结构放在CASE表达式中ORDER BY

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; 

演示

于 2018-11-01T12:14:12.933 回答
1

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

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

演示:db<>小提琴

如果不是,您将需要一个表格来存储排名值及其排名顺序。或者你像我一样用子查询模拟它:

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

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

演示:db<>fiddle

但请注意,更改枚举(添加、删除、重新排列值)可能非常困难。因此,仅在类型确实固定时才建议使用。否则,请使用带有外键的单独表带您回到第二部分。

于 2018-11-01T11:59:18.867 回答