排序字符升序,然后数字升序

时间:2019-04-11 14:12:00

标签: sql sql-server tsql sorting sql-order-by

在选择时是否有一个简单的技巧将排序顺序更改为“第一个字符值升序,然后数字值升序”?

   SELECT mycol
     FROM mytable
 ORDER BY mycol

结果:

1C
8Q
9G
AR
BZ
IT

使用DESC:

   SELECT mycol
     FROM mytable
 ORDER BY mycol DESC

结果:

IT
BZ
AR
9G
8Q
1C

所需结果:

AR
BZ
IT
1C
8Q
9G

6 个答案:

答案 0 :(得分:2)

我们可以在此处尝试使用ASCII函数和CASE表达式:

SELECT mycol
FROM mytable
ORDER BY
    CASE WHEN LEFT(mycol, 1) LIKE '[A-Z]' THEN 0 ELSE 1 END,
    LEFT(mycol, 1),
    CASE WHEN RIGHT(mycol, 1) LIKE '[A-Z]' THEN 0 ELSE 1 END,
    RIGHT(mycol, 1);

enter image description here

Demo

这里的逻辑使用四个级别的排序,mycol中两个字符中的每个都使用一对。 CASE表达式在数字前加上字母。之后,我们仅按数字或字母升序进行排序。

另一种解决方法是将您的列视为36的基数(10位加26个字母),然后根据该数字进行排序,然后转换回10进制的基数。但是,这可能比我上面发布的解决方案更丑陋,更令人费解。

答案 1 :(得分:2)

此选项会将列分为2个,以将数字和字母分开。

SELECT *
FROM (VALUES('1C'),('8Q'),('9G'),('AR'),('BZ'),('IT'))x(MyCol)
ORDER BY SUBSTRING(MyCol, 0, PATINDEX( '%[A-Z]%', MyCol)),
         SUBSTRING(MyCol, PATINDEX( '%[A-Z]%', MyCol), 10);

答案 2 :(得分:2)

只需:

SELECT *
FROM (VALUES 
    ('1C'),
    ('8Q'),
    ('9G'),
    ('AR'),
    ('BZ'),
    ('IT'),
    ('11'),
    ('2A')
) AS tbl(col)
ORDER BY CASE WHEN col LIKE '[0-9]%' THEN 2 ELSE 1 END
       , col

输出:

AR
BZ
IT
11
1C
2A
8Q
9G

答案 3 :(得分:0)

尝试一下:

DECLARE @mytable TABLE
( MyCol VARCHAR(3))

insert @mytable VALUES ('IT'),('BZ'),('AR'),('1C'),('8Q')

SELECT
     MyCol
FROM @mytable
ORDER BY PATINDEX('[0-9]%',MyCol),MyCol

答案 4 :(得分:0)

我对@TimBiegeleisen和@SalmanA的回答的变体:

SELECT mycol
FROM mytable
ORDER BY
    CASE WHEN mycol LIKE '[^0-9]%' THEN 0 ELSE 1 END,
    mycol;

(我不知道ORDER BY子句中列的索引是否会影响性能,但是请确保避免使用函数调用。)

编辑:嗯,实际上,答案与@SalmanA的答案几乎相同...

答案 5 :(得分:0)

我发现的另一种解决方案是使用EBCDIC归类对COLLATE子句使用ORDER BY。性能方面与其他解决方案一样快。也许写起来更容易,但是不加注释地阅读就有些棘手。一个优点是,它也可以用于超过1个或2个字符的列。

SELECT mycol
     FROM mytable
 ORDER BY mycol COLLATE SQL_EBCDIC278_CP1_CS_AS