2016-09-12 30 views
5

Czy ktoś może mi pomóc rozwiązać ten problem?
Mam dynamiczną listę wzorów, które chcę posortować, zawierają wartości alfanumeryczne i litery.Sortowanie alfanumeryczne na serwerze Sql 2008

CREATE TABLE dbo.Pattern (Pattern varchar(50) NULL) 
INSERT INTO dbo.Pattern (Pattern) VALUES ('A11') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('A12') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('A8') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('A2') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('B6') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('B21') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('B10') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('B3') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('B100') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('B2') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('AA') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('BA') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('A20') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('AB') 
INSERT INTO dbo.Pattern (Pattern) VALUES ('BB') 

SELECT Pattern FROM dbo.Pattern ORDER BY Pattern 

DROP Table dbo.Pattern 

Wynik pokazuje tak:

A11 
A12 
A2 
A20 
A8 
AA 
AB 
B10 
B100 
B2 
B21 
B3 
B6 
BA 
BB 

ale wszystkie chcę pokazać to jak tego wyniku:

AA 
A1 
A2 
A8 
A11 
A12 
A20 
AB 
BA 
B2 
B3 
B6 
B10 
B21 
B100 
BB 
+2

plus 1 dla przykładowych danych – TheGameiswar

+0

Czy potrafisz zdefiniować logikę za pożądanym rezultatem? Dlaczego 'AA' pojawia się po" B100 "? Który byłby pierwszy między "AAA" i "BA1"? Czemu? Jeśli potrafisz zdefiniować logikę, założę się, że możesz łatwo odpowiedzieć na swoje pytanie. –

+0

@TabAlleman, już edytuję zawartość wyniku, który powinien być wyprowadzany dla sortowania wzorców. – itsMacyAnn

Odpowiedz

1
SELECT Pattern 
FROM dbo.Pattern 
ORDER BY LEFT(Pattern,1), 
     CASE WHEN SUBSTRING(Pattern,2,LEN(Pattern)) LIKE '%[0-9]%' THEN CAST(SUBSTRING(Pattern,2,LEN(Pattern)) as int) 
      WHEN SUBSTRING(Pattern,2,LEN(Pattern)) = 'A' THEN 0 
      ELSE 10000000 END, 
      SUBSTRING(Pattern,2,LEN(Pattern)) 

Will:

Pattern 
AA 
A2 
A8 
A11 
A12 
A20 
AB 
BA 
B2 
B3 
B6 
B10 
B21 
B100 
BB 
1

Dla danych próbek, to jest blisko:

order by left(pattern, patindex('%[0-9]%', pattern)), 
     patindex('%[0-9]%', pattern), 
     len(pattern) asc, 
     pattern 

Ale chcesz wszystko alphas być ostatni, więc case jest potrzebne (chyba):

order by left(pattern, patindex('%[0-9]%', pattern)), 
     (case when pattern like '%[0-9]%' 
       then patindex('%[0-9]%', pattern) 
       else 999 
      end), 
     len(pattern) asc, 
     pattern 
+0

Nie zwraca danych wyjściowych zgodnie z powyższym pytaniem. czemu ? – Susang

+0

Ta logika oznaczałaby, że 'B1' pojawi się przed' A10', ponieważ ma on krótszą długość. –

+0

@ Suraz. . . Masz już odpowiedź, ale i tak naprawiłem tę odpowiedź. –

1
SELECT Pattern 
FROM dbo.Pattern 
ORDER BY CASE WHEN PATINDEX('%[0-9]%', Pattern) > 0 
       THEN LEFT(Pattern, PATINDEX('%[0-9]%', Pattern)-1) 
       ELSE Pattern 
     END, 
     CASE WHEN PATINDEX('%[0-9]%', Pattern) > 0 
       THEN CONVERT(INT, SUBSTRING(Pattern, PATINDEX('%[0-9]%', Pattern), LEN(Pattern))) 
       ELSE 0 
     END 

proszę szukać w sieci i przepełnienie stosu przed wysłaniem wiadomości.

referencyjny:http://www.essentialsql.com/use-sql-server-to-sort-alphanumeric-values/

+0

Zwraca "Niepoprawny parametr długości przekazany do błędu funkcji LEFT lub SUBSTRING". Wrzuć błąd dla wartości "AA", "BA", ponieważ te nie mają wartości liczbowej, więc 'LEWO ('AA', 0 - 1)' throw error. – Arulkumar

+0

Msg 537, Poziom 16, Stan 2, Wiersz 1 Nieprawidłowy parametr długości przekazywany do funkcji LEWO lub PODŁOŻA. – itsMacyAnn

+0

@ayakamacy Zaktualizowałem swoją odpowiedź, aby użyć wyrażenia "CASE" do obsługi wzorców zawierających tylko litery. –

0

bym separater alfa i num części:

ORDER BY 
    CASE WHEN PATINDEX('%[0-9]%', Pattern)=0 THEN 1 ELSE 0 END,--Put no-nums last 
    CASE WHEN PATINDEX('%[0-9]%', Pattern) != 0 THEN LEFT(Pattern, PATINDEX('%[0-9]%', Pattern)-1) ELSE Pattern END, 
    CASE WHEN PATINDEX('%[0-9]%', Pattern) != 0 THEN SUBSTRING(Pattern, PATINDEX('%[0-9]%', Pattern), LEN(Pattern)) END 
0

Zastosowanie krzyż zastosować w celu uproszczenia obliczeń w wierszu

wyjście
select pattern 
from pattern 
cross apply (
    select leftLen = isnull(nullif(patindex('%[0-9]%', pattern),0) - 1, len(pattern)) 
      ,totalLen = len(pattern) 
    ) c 
order by 
case leftLen when totalLen then 2 else 1 end, 
left(Pattern, leftLen), 
cast(right(Pattern, totalLen-leftLen) as int) 
Powiązane problemy