sql ORDER BY特定顺序的多个值?

Phi*_*ord 79 sql postgresql sql-order-by

好吧,我有一个带有索引键和非索引字段的表.我需要查找具有特定值的所有记录并返回该行.我想知道我是否可以按多个值排序.

例:

id     x_field
--     -----
123    a
124    a
125    a
126    b
127    f
128    b
129    a
130    x
131    x
132    b
133    p
134    p
135    i
Run Code Online (Sandbox Code Playgroud)

伪:希望结果像这样订购, where ORDER BY x_field = 'f', 'p', 'i', 'a'

SELECT *
FROM table
WHERE id NOT IN (126)
ORDER BY x_field 'f', 'p', 'i', 'a'
Run Code Online (Sandbox Code Playgroud)

结果将是:

id     x_field
--     -----
127    f
133    p
134    p
135    i
123    a
124    a
125    a
129    a
Run Code Online (Sandbox Code Playgroud)

语法有效,但是当我执行查询时,它永远不会返回任何结果,即使我将其限制为1条记录.还有另一种方法可以解决这个问题吗?

将x_field视为测试结果,我需要验证属于该条件的所有记录.我想通过失败的值,传递的值来排序测试结果.所以我可以先验证失败的值,然后使用ORDER BY验证传递的值.

我做不到的事:

  • GROUP BY,因为我需要返回特定的记录值
  • 在哪里x_field IN('f','p','i','a'),我需要所有的值,因为我正在尝试使用一个查询进行多次验证测试.并且x_field值不是DESC/ASC顺序

在写完这个问题后,我开始认为我需要重新考虑这个问题,哈哈!

gbn*_*gbn 158

...
WHERE
   x_field IN ('f', 'p', 'i', 'a') ...
ORDER BY
   CASE x_field
      WHEN 'f' THEN 1
      WHEN 'p' THEN 2
      WHEN 'i' THEN 3
      WHEN 'a' THEN 4
      ELSE 5 --needed only is no IN clause above. eg when = 'b'
   END, id
Run Code Online (Sandbox Code Playgroud)


peu*_*feu 25

您可以使用LEFT JOIN和"VALUES('f',1),('p',2),('a',3),('i',4)"并使用订单中的第二列-by表达.Postgres将使用Hash Join,如果你有很多值,它将比一个巨大的CASE快得多.并且它更容易自动生成.

如果这个订购信息是固定的,那么它应该有自己的表.

  • 这是迄今为止最优雅的解决方案! (6认同)

Mar*_*c B 21

尝试:

ORDER BY x_field='F', x_field='P', x_field='A', x_field='I'
Run Code Online (Sandbox Code Playgroud)

您处于正确的轨道上,但是只将x_field放在F值上,其他3个被视为常量,而不是与数据集中的任何内容进行比较.

  • 是的,它在Postgres中有效.请注意,此解决方案是您按相反的顺序排序结果.所以你必须按相反的顺序放置字段:ORDER BY x_field ='A',x_field ='I',x_field ='P',x_field ='F', (6认同)
  • 要反转并获得正确的顺序,您还可以添加 (!=) 运算符:ORDER BY x_field!='f', x_field!='p', x_field!='i', x_field!='a' (2认同)

Guf*_*ffa 13

使用case开关将代码转换为可以排序的数字:

ORDER BY
  case x_field
  when 'f' then 1
  when 'p' then 2
  when 'i' then 3
  when 'a' then 4
  else 5
  end
Run Code Online (Sandbox Code Playgroud)


And*_*rus 7

这些CASEORDER BY建议应该都有效,但我会建议一匹不同颜色的马.假设只有合理数量的值x_field并且您已经知道它们是什么,请创建一个枚举类型,其中包含F,P,A和I作为值(加上适用的其他任何可能的值).枚举将按其CREATE声明隐含的顺序排序.此外,您可以使用有意义的值名称 - 您的真实应用程序可能会这样做,并且您只是为了机密性而屏蔽它们 - 没有浪费的空间,因为只存储了序数位置.


rep*_*ept 7

我找到了一个更清洁的解决方案:

ORDER BY array_position(ARRAY['f', 'p', 'i', 'a']::varchar[], x_field)
Run Code Online (Sandbox Code Playgroud)

注意:array_position需要Postgres v9.5或更高版本。