1

我有一张订单表。对于每个订单,我们允许用户输入他们的(非唯一的)订单号。这可以让我们为所欲为。

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

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

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

42
Order8
MyOrder
9
Order63

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

42
9
MyOrder
Order63
Order8

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

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

9
42
MyOrder
Order8
Order63

我希望它们对字符串按字典顺序排列,但对数字按数字排列。我想到了一些可行的方法:

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

演示:http ://sqlfiddle.com/#!2/7973e/2

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

4

2 回答 2

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 的作者。

于 2012-08-17T18:30:03.633 回答
2

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

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

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

于 2012-08-17T18:30:49.663 回答