如何在MySQL中对A1,A2,A3,B1,B2,B3,...,AA1,AA2,AA3进行排序?

时间:2013-04-01 12:07:51

标签: mysql sql select

我有一个如下所示的数据集:

+--------+
| Square |
+--------+
| A1     |
| A10    |
| A2     |
| A3     |
| A4     |
| A5     |
| A6     |
| A7     |
| A8     |
| A9     |
| B1     |
| B10    |
| B2     |
| B3     |
| B4     |
| B5     |
| B6     |
| B7     |
| B8     |
| B9     |

...

| AA1    |
| AA10   |
| AA2    |
| AA3    |
| AA4    |
| AA5    |
| AA6    |
| AA7    |
| AA8    |
| AA9    |
+--------+

前缀从A#-Z#开始,然后转到AA#-ZZ#并继续,最多2个字母(即它永远不会越过ZZ)。数字后缀可以是任何长度(即A1,A10,A100,A1000等)。

如何对这些进行排序并使结果集如下:

+--------+
| Square |
+--------+
| A1     |
| A2     |
| A3     |
| A4     |
| A5     |
| A6     |
| A7     |
| A8     |
| A9     |
| A10    |
| B1     |
| B2     |
| B3     |
| B4     |
| B5     |
| B6     |
| B7     |
| B8     |
| B9     |
| B10    |

...

| AA1    |
| AA2    |
| AA3    |
| AA4    |
| AA5    |
| AA6    |
| AA7    |
| AA8    |
| AA9    |
| AA10   |
+--------+

5 个答案:

答案 0 :(得分:6)

你需要重组你的表,否则你可能会有这样的低效查询,

SELECT  Square
FROM    Table1
ORDER   BY         
        CASE WHEN Square REGEXP '^[A-Z]{2}'
            THEN 1 
            ELSE 0
        END ASC,
        CASE WHEN Square REGEXP '^[A-Z]{2}'
            THEN LEFT(Square, 2)
            ELSE LEFT(Square, 1)
        END ASC,
        CASE WHEN Square REGEXP '^[A-Z]{2}'
            THEN CAST(RIGHT(Square, LENGTH(Square) - 2) AS SIGNED)
            ELSE CAST(RIGHT(Square, LENGTH(Square) - 1) AS SIGNED)
        END ASC

或使用IF

SELECT  Square
FROM    Table1
ORDER   BY Square REGEXP '^[A-Z]{2}' ASC,
           IF(Square REGEXP '^[A-Z]{2}', LEFT(Square, 2), LEFT(Square, 1)),
           CAST(IF(Square REGEXP '^[A-Z]{2}', RIGHT(Square, LENGTH(Square) - 2), RIGHT(Square, LENGTH(Square) - 1)) AS SIGNED)

答案 1 :(得分:0)

也许如果我没弄错的话,这会有用:

SELECT Square
FROM table
ORDER BY CASE WHEN
     SUBSTR(Square, 2, 1) BETWEEN 'A' AND 'Z' 
     THEN CONCAT(LEFT(Square, 2),
         LPAD(RIGHT(Square, LENGTH(Square) - 2), 6, '000000'))
     ELSE CONCAT(LEFT(Square, 1),
         LPAD(RIGHT(Square(LENGTH(Square) - 1), 6, '000000'))
    END

答案 2 :(得分:0)

如果能够,我强烈建议您更改数据库结构。这些应存储在2个单独的字段中。这是一种可以执行排序的方法,但也可以让您按正确的方向重新构建表格:

select square, left(square,2) prefix, mid(square,3) suffix
from yourtable
where left(square,2) not regexp '[0-9]'
union
select square, left(square,1) prefix, mid(square,2) suffix
from yourtable
where left(square,2) regexp '[0-9]'
order by prefix, cast(sufix as signed)

SQL Fiddle Demo

这样,您可以看到前缀和后缀被分解。这也可以使用没有联合的case / if语句来完成。

答案 3 :(得分:0)

这是构建表格的更好方法

 letter  number  
   A      1
   A      2
   A      3
  .....so on

然后你的查询将很容易

  select concat(letter,number) as Square from your_table
  order by letter , number

DEMO HERE

答案 4 :(得分:-1)

我现在无法对此进行全面测试,但它对我有用,而且与之前的解决方案完全不同,我很想知道它是否适用于您的问题。我非常相似,改变数据库结构不是一个选项,因为我正在排序的是一个用户输入......但我的解决方案无论大小如何,都比建议的更简单:

SELECT  Square
FROM    Table1
ORDER BY LENGTH(Square), Square