我有一张订单表。对于每个订单,我们允许用户输入他们的(非唯一)订单号。这可以是我们想要的任何东西。
我将这些订单显示在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
但是唉,我仍然得到相同的结果(因为这些数字会被重新转换回字符串)。如何以我想要的方式对这些值进行排序?如果只有某种方法可以将字符串“转换”为一种数值。
答案 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)对混合(文本/数字)订单号进行排序,则需要更多工作。