按数值和词典值排序字段

时间:2012-08-17 17:52:39

标签: mysql sorting

我有一张订单表。对于每个订单,我们允许用户输入他们的(非唯一)订单号。这可以是我们想要的任何东西。

我将这些订单显示在HTML表格中,可以按各种字段对订单进行排序,例如订单号。

我们的一位客户注意到排序问题。由于订单号存储为VARCHAR,因此按字典顺序排序。问题是,并非所有订单号都是数字,有些是单词,其他是字母数字。

所以,例如,我可以有这样的订单号:

42
Order8
MyOrder
9
Order63

使用ORDER BY orderNumber排序时,我得到:

42
9
MyOrder
Order63
Order8

DEMO:http://sqlfiddle.com/#!2/7973e/1

这不是我想要的。我希望它们像这样排序:

9
42
MyOrder
Order8
Order63

我希望它们是字符串的词典,但数字是数字。我想到了可能有用的东西:

ORDER BY IFNULL(NULLIF(CAST(orderNumber AS SIGNED), 0), orderNumber)

DEMO:http://sqlfiddle.com/#!2/7973e/2

但是唉,我仍然得到相同的结果(因为这些数字会被重新转换回字符串)。如何以我想要的方式对这些值进行排序?如果只有某种方法可以将字符串“转换”为一种数值。

2 个答案:

答案 0 :(得分:4)

当您看到数字值时,可以尝试用零填充订单号。看到这个,例如:

http://sqlfiddle.com/#!2/7973e/21

SELECT  
  CASE 
    WHEN CAST(orderNumber AS SIGNED) != 0 THEN LPAD(orderNumber, 10, '0')
    ELSE orderNumber 
  END as padded, 
  orders.*
FROM orders
ORDER BY
  padded

结果:

|     PADDED | ORDERID | ORDERNUMBER |
--------------------------------------
| 0000000009 |       4 |           9 |
| 0000000042 |       1 |          42 |
|    MyOrder |       3 |     MyOrder |
|    Order63 |       5 |     Order63 |
|     Order8 |       2 |      Order8 |

完全披露:我是SQL Fiddle的作者。

答案 1 :(得分:2)

您可以通过以下方式接近您想要的内容:

ORDER BY CASE WHEN CONVERT(OrderNumber, SIGNED INTEGER)= 0 
         THEN 1e50
         ELSE CONVERT(OrderNumber, SIGNED INTEGER)
         END ASC, OrderNumber ASC

但是,如果您需要按其最后一位数字(例如Order63,Order8)对混合(文本/数字)订单号进行排序,则需要更多工作。