sql ORDER BY 按特定顺序排列多个值?

Posted

技术标签:

【中文标题】sql ORDER BY 按特定顺序排列多个值?【英文标题】:sql ORDER BY multiple values in specific order? 【发布时间】:2011-09-13 23:50:27 【问题描述】:

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

例子:

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

伪:希望结果像这样排序,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 顺序

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

【问题讨论】:

也许是工会?按照您希望返回结果的顺序构建单独的查询,然后合并这些查询? 【参考方案1】:
...
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

【讨论】:

【参考方案2】:

试试:

ORDER BY x_field='f', x_field='p', x_field='i', x_field='a'

您在正确的轨道上,但是通过仅将 x_field 放在 'f' 值上,其他三个被视为常量,而不是与数据集。

【讨论】:

Postgres 是否支持隐式布尔值?如果是,布尔值如何排序? 我喜欢这个解决方案,但它没有再返回任何东西。 @gbn,是的和错误的 是的,它在 Postgres 中有效。此解决方案的注意事项是您会以相反的顺序对结果进行排序。所以你必须把字段倒序排列:ORDER BY x_field='A', x_field='I', x_field='P', x_field='F', 要反转并获得正确的顺序,您还可以添加 (!=) 运算符:ORDER BY x_field!='f', x_field!='p', x_field!='i', x_field !='a'【参考方案3】:

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

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

【讨论】:

这是迄今为止最优雅的解决方案! 如果有人需要使用建议方法的完整查询,我添加了它here。【参考方案4】:

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

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

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

【讨论】:

需要注意的是,array_position() 仅在 Postgres v9.5 及更高版本中可用,afaik。 谢谢,比起 CASE 方法更喜欢这个。也适用于整数; array_position(ARRAY[1, 0]::integer[], x_field)【参考方案5】:

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

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

对于使用 CASE ORDER BY 的新手来说,这可能很有用

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

【讨论】:

【参考方案8】:

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

select tt.id, tt.x_field
from target_table as tt
-- Here we join our target_table with order_table to specify custom ordering.
left join
    (values ('f', 1), ('p', 2), ('i', 3), ('a', 4)) as order_table (x_field, order_num)
    on order_table.x_field = tt.x_field
order by
    order_table.order_num, -- Here we order values by our custom order.
    tt.x_field;            -- Other values can be ordered alphabetically, for example.

这里是完整的demo。

【讨论】:

【参考方案9】:

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

这里是一个例子,如何按 case-statement 的结果排序:

  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

【讨论】:

虽然这段代码 sn-p 可以解决问题,但它没有解释为什么或如何回答这个问题。请include an explanation for your code,因为这确实有助于提高您的帖子质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。【参考方案10】:

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

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

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

这使得I在前,P在后,A作为最后一个,F在最后一个之前。

【讨论】:

【参考方案11】:

如果您之后使用 mysql 4.0,请考虑使用 FIELD() 。它通过下一个参数返回第一个参数的索引位置,并且区分大小写。

ORDER BY FIELD(x_field, 'f', 'p', 'i', 'a')

【讨论】:

【参考方案12】:

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

【讨论】:

以上是关于sql ORDER BY 按特定顺序排列多个值?的主要内容,如果未能解决你的问题,请参考以下文章

具有特定顺序的 SQL ORDER BY,首先以特定单词开头,然后是升序 [重复]

MySQL排序:SELECT ORDER BY

SQL里面的order by语句是干啥用的?

若SQL语句中的ORDER BY短语中指定了多个字段,则( )。

当sql语句中where,order by,group by同时使用查询sql语句中三者的顺序

SQL基础-order by