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

时间:2011-06-13 14:48:45

标签: 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

pseudo:希望结果像这样排序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'

结果将是:

id     x_field
--     -----
127    f
133    p
134    p
135    i
123    a
124    a
125    a
129    a

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

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

我不能做的事情:

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

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

11 个答案:

答案 0 :(得分:138)

...
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

答案 1 :(得分:22)

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

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

答案 2 :(得分:17)

尝试:

ORDER BY x_field='F', x_field='P', x_field='A', x_field='I'

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

答案 3 :(得分:11)

使用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

答案 4 :(得分:6)

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

答案 5 :(得分:5)

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

ORDER BY array_position(ARRAY['f', 'p', 'i', 'a']::varchar[], x_field)

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

答案 6 :(得分:0)

您可以按选定的列或其他表达式进行排序。

在此示例如何根据案例陈述的结果进行排序:

  SELECT col1
       , col2
    FROM tbl_Bill
   WHERE col1 = 0
ORDER BY -- order by case-statement
    CASE WHEN tbl_Bill.IsGen = 0 THEN 0
         WHEN tbl_Bill.IsGen = 1 THEN 1
         ELSE 2 END

结果将是一个列表,列表以“ IsGen = 0”行开头,然后是“ IsGen = 1”行,所有其他行都以结尾结尾。

您可以在末尾添加更多订单参数:

  SELECT col1
       , col2
    FROM tbl_Bill
   WHERE col1 = 0
ORDER BY -- order by case-statement
    CASE WHEN tbl_Bill.IsGen = 0 THEN 0
         WHEN tbl_Bill.IsGen = 1 THEN 1
         ELSE 2 END,
         col1,
         col2

答案 7 :(得分:0)

对于使用 CASE 进行 ORDER BY 的人来说,这可能会有用

ORDER BY 
    CASE WHEN GRADE = 'A' THEN 0
         WHEN GRADE = 'B' THEN 1
         ELSE 2 END

答案 8 :(得分:0)

由于我没有足够的声誉来撰写评论,因此将其添加为新答案。

您可以将asc或desc添加到order by子句中。

ORDER BY x_field='A' ASC, x_field='I' DESC, x_field='P' DESC, x_field='F' ASC

这使我排在第一位,P位居第二,A位排在最后,F位排在最后。

答案 9 :(得分:0)

@bobflux的answer很棒。我想通过添加使用建议方法的完整查询来扩展它。

<mat-select name="countryString" panelClass="panel-custom-width" [(value)]="selectedCountry">
    <mat-option [value]="'GB'">Great Britain</mat-option>
    <mat-option [value]="'US'">United States</mat-option>
    <mat-option [value]="'CA'">Canada</mat-option>
</mat-select>

这里是完整的demo

答案 10 :(得分:-2)

您可以按顺序使用位置(文本中的文字)来排序序列