按数值显示按字母顺序排列的列表

时间:2017-09-28 04:40:18

标签: sql-server sql-server-2008 sql-server-2008-r2 sql-order-by

我有数据有点像这样: -

BQS 1 (CP)
BQS 2 (CP)
BQS 3 (CP)
BQS 5 (PB1)
CAPSULE FILLING 3 ZRO (PB4)
CAPSULE FILLING 6 A150T(PB4)
COMPRESSION 1 (PB4)
COMPRESSION 12(PB4)
COMPRESSION 3 (PB4)
COMPRESSION 4 (PB4 EX)
COMPRESSION 5 (PB4 EX)
PHARMA PACK 1 (CP)
PHARMA PACK 2 (CP)
PP III (CP)

我想要这样的数据: -

BQS 1 (CP)
BQS 2 (CP)
BQS 3 (CP)
BQS 5 (PB1)
CAPSULE FILLING 3 ZRO (PB4)
CAPSULE FILLING 6 A150T(PB4)
COMPRESSION 1 (PB4)
COMPRESSION 3 (PB4)
COMPRESSION 4 (PB4 EX)
COMPRESSION 5 (PB4 EX)
COMPRESSION 12(PB4)
PHARMA PACK 1 (CP)
PHARMA PACK 2 (CP)
PP III (CP)

当你比较它们时,你可以看到Compression 12中的差异。如何编写查询以获得所需的输出?

1 个答案:

答案 0 :(得分:1)

可以这样做,但你必须解析数字并将它们转换为INT,然后才能将它们排序为数字。这里有几个不同的例子。我不会声称要么是过于优雅,但实际上不会有一个,没有在你的表中添加索引排序列。

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData;

CREATE TABLE #TestData (
    SomeString VARCHAR(100)
    );
INSERT #TestData(SomeString) VALUES
    ('BQS 1 (CP)'),
    ('BQS 2 (CP)'),
    ('BQS 3 (CP)'),
    ('BQS 5 (PB1)'),
    ('CAPSULE FILLING 3 ZRO (PB4)'),
    ('CAPSULE FILLING 6 A150T(PB4)'),
    ('COMPRESSION 1 (PB4)'),
    ('COMPRESSION 3 (PB4)'),
    ('COMPRESSION 4 (PB4 EX)'),
    ('COMPRESSION 5 (PB4 EX)'),
    ('COMPRESSION 12(PB4)'),
    ('PHARMA PACK 1 (CP)'),
    ('PHARMA PACK 2 (CP)'),
    ('PP III (CP)');

--====================================================================

-- option 1...
SELECT
    Option_1 = td.SomeString
FROM
    #TestData td
    CROSS APPLY ( VALUES (NULLIF(PATINDEX('%[0-9]%', td.SomeString), 0)) ) x1 (N)
    CROSS APPLY ( VALUES (NULLIF(CHARINDEX('(', REPLACE(td.SomeString, ' ', '('), x1.N), 0)) ) x2 (P)
    CROSS APPLY ( VALUES (LEFT(td.SomeString, ISNULL(x1.N - 2, 100))) ) s1 (Sort1)
    CROSS APPLY ( VALUES (TRY_CAST(SUBSTRING(td.SomeString, ISNULL(x1.N, 1), ISNULL(x2.P - x1.N, 100)) AS INT)) ) s2 (Sort2)
ORDER BY
    s1.Sort1,
    s2.Sort2;

-- option 2...
SELECT 
    OPTION_2 = td.SomeString
FROM
    #TestData td
    CROSS APPLY ( VALUES (NULLIF(PATINDEX('%[0-9]%', td.SomeString), 0)) ) x (N)
    CROSS APPLY ( VALUES (LEFT(td.SomeString, ISNULL(x.N - 2, 100))) ) s1 (Sort1)
    CROSS APPLY ( VALUES (CASE 
                            WHEN SUBSTRING(td.SomeString, x.N, 5) NOT LIKE '%[^0-9]%' THEN CAST(SUBSTRING(td.SomeString, x.N, 5) AS INT) 
                            WHEN SUBSTRING(td.SomeString, x.N, 4) NOT LIKE '%[^0-9]%' THEN CAST(SUBSTRING(td.SomeString, x.N, 4) AS INT)
                            WHEN SUBSTRING(td.SomeString, x.N, 3) NOT LIKE '%[^0-9]%' THEN CAST(SUBSTRING(td.SomeString, x.N, 3) AS INT)
                            WHEN SUBSTRING(td.SomeString, x.N, 2) NOT LIKE '%[^0-9]%' THEN CAST(SUBSTRING(td.SomeString, x.N, 2) AS INT)
                            WHEN SUBSTRING(td.SomeString, x.N, 1) NOT LIKE '%[^0-9]%' THEN CAST(SUBSTRING(td.SomeString, x.N, 1) AS INT)
                        END) ) s2 (Sort2)
ORDER BY
    s1.Sort1,
    s2.Sort2;

结果...

Option_1
----------------------------------------
BQS 1 (CP)
BQS 2 (CP)
BQS 3 (CP)
BQS 5 (PB1)
CAPSULE FILLING 3 ZRO (PB4)
CAPSULE FILLING 6 A150T(PB4)
COMPRESSION 1 (PB4)
COMPRESSION 3 (PB4)
COMPRESSION 4 (PB4 EX)
COMPRESSION 5 (PB4 EX)
COMPRESSION 12(PB4)
PHARMA PACK 1 (CP)
PHARMA PACK 2 (CP)
PP III (CP)

OPTION_2
-----------------------------------------
BQS 1 (CP)
BQS 2 (CP)
BQS 3 (CP)
BQS 5 (PB1)
CAPSULE FILLING 3 ZRO (PB4)
CAPSULE FILLING 6 A150T(PB4)
COMPRESSION 1 (PB4)
COMPRESSION 3 (PB4)
COMPRESSION 4 (PB4 EX)
COMPRESSION 5 (PB4 EX)
COMPRESSION 12(PB4)
PHARMA PACK 1 (CP)
PHARMA PACK 2 (CP)
PP III (CP)