2016-01-20 306 views
3

我有以下SQL:如何按數字順序對字母數字SQL Server NVARCHAR列進行排序?

SELECT fldTitle 
FROM tblTrafficAlerts 
ORDER BY fldTitle 

它返回下列順序的結果(從NVARCHAR列):

A1M northbound within J17 Congestion 
M1 J19 southbound exit Congestion 
M1 southbound between J2 and J1 Congestion 
M23 northbound between J8 and J7 Congestion 
M25 anti-clockwise between J13 and J12 Congestion 
M25 clockwise between J8 and J9 Broken down vehicle 
M3 eastbound at the Fleet services between J5 and J4A Congestion 
M4 J19 westbound exit Congestion 

你會看到M23和M25是在M3以上所列和M4行,這看起來並不令人滿意,而且如果掃描更長的結果列表,您不希望按照此順序讀取它們。

所以我想按字母順序排序,然後數值結果,看起來像:

A1M northbound within J17 Congestion 
M1 J19 southbound exit Congestion 
M1 southbound between J2 and J1 Congestion 
M3 eastbound at the Fleet services between J5 and J4A Congestion 
M4 J19 westbound exit Congestion 
M23 northbound between J8 and J7 Congestion 
M25 anti-clockwise between J13 and J12 Congestion 
M25 clockwise between J8 and J9 Broken down vehicle 

因此M3和M4出現上述M23和M25。

+0

標籤DBMS。 (答案可能取決於使用的產品。) – jarlh

+0

Microsoft SQL Server 2008 - 感謝您的標籤編輯建議! – Rich

+2

@JaydipJ該運營商尚未表示未按預期工作。他問的是如何排序與默認 –

回答

2

這應該處理它。還添加了一些奇怪的數據,以確保排序也適用於認爲:

SELECT x 
FROM 
(values 
('A1M northbound within J17 Congestion'), 
('M1 J19 southbound exit Congestion'), 
('M1 southbound between J2 and J1 Congestion'), 
('M23 northbound between J8 and J7 Congestion'), 
('M25 anti-clockwise between J13 and J12 Congestion'), 
('M25 clockwise between J8 and J9 Broken down vehicle'), 
('M3 eastbound at the Fleet services between J5 and J4A Congestion'), 
('M4 J19 westbound exit Congestion'),('x'), ('2'), ('x2')) x(x) 
ORDER BY 
    LEFT(x, patindex('%_[0-9]%', x +'0')), 
    0 + STUFF(LEFT(x, 
    PATINDEX('%[0-9][^0-9]%', x + 'x1x')),1, 
    PATINDEX('%_[0-9]%', x + '0'),'') 

結果:使用

2 
A1M northbound within J17 Congestion 
M1 J19 southbound exit Congestion 
M1 southbound between J2 and J1 Congestion 
M3 eastbound at the Fleet services between J5 and J4A Congestion 
M4 J19 westbound exit Congestion 
M23 northbound between J8 and J7 Congestion 
M25 anti-clockwise between J13 and J12 Congestion 
M25 clockwise between J8 and J9 Broken down vehicle 
x 
x2 
+0

這完美的作品,謝謝!爲了完整起見,我的結果查詢是:SELECT fldTitle FROM tblTrafficAlerts ORDER BY LEFT(fldTitle,PATINDEX('%_ [0-9]%',fldTitle +'0')),0 + STUFF(LEFT(fldTitle, PATINDEX('%[0-9] [^ 0-9]%',fldTitle +'x1x')),1,PATINDEX('%_ [0-9]%',fldTitle +'0'),'' ) – Rich

0

也許這並不漂亮,但它的工作:

DECLARE @tblTrafficAlerts TABLE 
(
    fldTitle NVARCHAR(500) 
); 

INSERT INTO @tblTrafficAlerts (fldTitle) 
VALUES (N'A1M northbound within J17 Congestion') 
    , (N'M1 J19 southbound exit Congestion') 
    , (N'M1 southbound between J2 and J1 Congestion') 
    , (N'M23 northbound between J8 and J7 Congestion') 
    , (N'M25 anti-clockwise between J13 and J12 Congestion') 
    , (N'M25 clockwise between J8 and J9 Broken down vehicle') 
    , (N'M3 eastbound at the Fleet services between J5 and J4A Congestion') 
    , (N'M4 J19 westbound exit Congestion'); 

SELECT * 
FROM @tblTrafficAlerts AS T 
CROSS APPLY (SELECT PATINDEX('%[0-9]%', T.fldTitle)) AS N(NumIndex) 
CROSS APPLY (SELECT PATINDEX('%[0-9][^0-9]%', T.fldTitle)) AS NN(NextLetter) 
ORDER BY SUBSTRING(T.fldTitle, 0, N.NumIndex), CONVERT(INT, SUBSTRING(T.fldTitle, N.NumIndex, NN.NextLetter - 1)); 

這將提取之前的一切第一號,爲了通過它,然後用它提取數量和順序爲整數。

這是輸出:

╔══════════════════════════════════════════════════════════════════╗ 
║        fldTitle        ║ 
╠══════════════════════════════════════════════════════════════════╣ 
║ A1M northbound within J17 Congestion        ║ 
║ M1 J19 southbound exit Congestion        ║ 
║ M1 southbound between J2 and J1 Congestion      ║ 
║ M3 eastbound at the Fleet services between J5 and J4A Congestion ║ 
║ M4 J19 westbound exit Congestion         ║ 
║ M23 northbound between J8 and J7 Congestion      ║ 
║ M25 anti-clockwise between J13 and J12 Congestion    ║ 
║ M25 clockwise between J8 and J9 Broken down vehicle    ║ 
╚══════════════════════════════════════════════════════════════════╝ 
0
SELECT fldTitle FROM tblTrafficAlerts order by LEFT(fldTitle , CHARINDEX(' ', fldTitle) - 1), fldTitle 

或使用patindex

ORDER BY LEFT(Col1,PATINDEX('%[^0-9]%',Col1)-1) 
0

我想是這樣的:

編輯:我有兩種portiions分離這樣的:首字母和第二部分。這可以讓你 - 如果需要的話 - - 以數字方式處理第二部分(但第一行有一個令人不安的「M」......)

第二步操作會更容易: ,檢查長度並在需要時在排序上添加'0'。

DECLARE @tblTrafficAlerts TABLE(fldTitle VARCHAR(500)); 

INSERT INTO @tblTrafficAlerts VALUES 
('A1M northbound within J17 Congestion') 
,('M1 J19 southbound exit Congestion') 
,('M1 southbound between J2 and J1 Congestion') 
,('M23 northbound between J8 and J7 Congestion') 
,('M25 anti-clockwise between J13 and J12 Congestion') 
,('M25 clockwise between J8 and J9 Broken down vehicle') 
,('M3 eastbound at the Fleet services between J5 and J4A Congestion') 
,('M4 J19 westbound exit Congestion'); 

SELECT ta.fldTitle 
     ,Leading.Letter 
     ,Leading.SecondPart 
FROM @tblTrafficAlerts AS ta 
CROSS APPLY(SELECT SUBSTRING(ta.fldTitle,1,1) AS Letter 
        ,SUBSTRING(ta.fldTitle,2,CHARINDEX(' ',ta.fldTitle)-1) AS SecondPart) AS Leading 
ORDER BY Leading.Letter,CASE WHEN LEN(Leading.SecondPart)=1 THEN Leading.SecondPart + '0' ELSE Leading.SecondPart END 

結果:

fldTitle               Letter SecondPart 
A1M northbound within J17 Congestion        A  1M 
M1 J19 southbound exit Congestion         M  1 
M1 southbound between J2 and J1 Congestion       M  1 
M23 northbound between J8 and J7 Congestion      M  23 
M25 anti-clockwise between J13 and J12 Congestion     M  25 
M25 clockwise between J8 and J9 Broken down vehicle    M  25 
M3 eastbound at the Fleet services between J5 and J4A Congestion M  3 
M4 J19 westbound exit Congestion         M  4