2013-05-31 7 views
6

ich SQL Server verwende, ist die Spalte ein VARCHAR(50) und ich mag es so sortieren:Sortierung VARCHAR Spalt mit alphanumerischen Eingaben

1A   
1B   
2   
2   
3   
4A   
4B   
4C   
5A   
5B   
5C   
5N   
14 Draft   
21   
22A   
22B   
23A   
23B   
23C   
23D   
23E   
25   
26   
FR01584   
MISC 

Was ich bisher habe, ist:

Select * 
From viewASD 
ORDER BY 
    Case When IsNumeric(LEFT(asdNumNew,1)) = 1 
     Then CASE When IsNumeric(asdNumNew) = 1 
        Then Right(Replicate('0',20) + asdNumNew + '0', 20) 
        Else Right(Replicate('0',20) + asdNumNew, 20) 
       END 
     When IsNumeric(LEFT(asdNumNew,1)) = 0 
     Then Left(asdNumNew + Replicate('',21), 20) 
    End 

Aber diese SQL-Anweisung setzt '14 Draft 'direkt nach' 26 '.

Könnte jemand helfen? Danke

Antwort

3

Ihre WHERE-Anweisung ist ... seltsam komplex.

Es sieht so aus, als ob Sie nach allen führenden numerischen Ziffern in ganzzahliger Reihenfolge sortieren und dann nach dem Rest sortieren möchten. Wenn dies der Fall ist, sollten Sie das als separate Klauseln tun, anstatt alles in einem zu tun. Das spezielle Problem, das Sie haben, ist, dass Sie nur eine einstellige Zahl zulassen, anstatt zwei oder mehr. (Und es gibt No such thing as two.)

Hier ist Ihr Fix, zusammen mit einem SQLFiddle, mit zwei separaten berechneten Spalten Tests für Ihre ORDER BY. (Beachten Sie, dass dies der numerische Teil von asdNumNew übernimmt in einem T-SQL int passen. Wenn nicht, werden Sie die CAST anpassen müssen und den Maximalwert auf dem ersten ELSE.)

SELECT * FROM viewASD 
ORDER BY 
CASE 
    WHEN ISNUMERIC(asdNumNew)=1 
    THEN CAST(asdNumNew as int) 

    WHEN PATINDEX('%[^0-9]%',asdNumNew) > 1 
    THEN CAST(
    LEFT(
     asdNumNew, 
     PATINDEX('%[^0-9]%',asdNumNew) - 1 
    ) as int) 

    ELSE 2147483648 
END, 


CASE 
    WHEN ISNUMERIC(asdNumNew)=1 
    THEN NULL 

    WHEN PATINDEX('%[^0-9]%',asdNumNew) > 1 
    THEN SUBSTRING(
     asdNumNew, 
     PATINDEX('%[^0-9]%',asdNumNew) , 
     50 
    ) 

    ELSE asdNumNew 
END 
+0

Ich sehe! Vielen Dank! Ich wusste nicht viel über die PATINDEX-Funktion, und jetzt, seit ich nachgeschaut habe, scheint es viel einfacher zu verstehen. – terezzy

0

Wenn alle Zahlen innerhalb der Zeichenfolge recht klein sind, sagen nicht 10 Stellen übersteigt, Sie alle Zahlen in der Zeichenkette erweitern kann genau 10 Stellen zu sein:

123A -> 0000000123A

S4 -> S0000000004 

A3B89 -> A0000000003B0000000089

und so weiter und dann sortieren sie

-- Expand all numbers within S by zeros to be MaxLen 
create function [dbo].ExpandNumbers(@S VarChar(4000), @maxlen integer) returns VarChar(4000) 
as 
begin 
    declare @result VarChar(4000); 
    declare @buffer VarChar(4000); 
    declare @Ch Char; 

    declare @i integer; 

    set @buffer = ''; 
    set @result = ''; 
    set @i = 1; 

    while (@i <= len(@S)) 
    begin 
     set @Ch = substring(@S, @i, 1); 


     if ((@Ch >= '0') and (@Ch <= '9')) 
     set @buffer = @buffer + @Ch 
     else 
     begin 
      if (len(@buffer) > 0) 
      set @result = @result + right(replicate('0', @maxlen) + @buffer, @maxlen); 

      set @buffer = ''; 
      set @result = @result + @Ch; 
     end; 

     set @i = @i + 1; 
    end; 

    if (len(@buffer) > 0) 
    set @result = @result + right(replicate('0', @maxlen) + @buffer, @maxlen); 

    return @result; 
end; 

-- Final query is 

    select * 
    from viewASD 
order by [dbo].ExpandNumbers(asdNumNew) 
0

VERSUCHEN SIE DIESE
declare @t Tabelle (Anzahl nvarchar (20)) Einsatz in @t wählen 'L010' Verbindung alle wählen 'L011' Verbindung alle wählen 'L011' Verbindung alle s elect 'L001' union all 'L012' Vereinigung alle wählen '18'
Union Alle wählen '8' Vereinigung alle wählen '17'

union all select 'B004'  
union all SELECT 'B006'  
union all SELECT 'B008' 
union all SELECT 'B018' 
union all SELECT 'UG001' 
union all SELECT 'UG011' 
union all SELECT 'G001'  
union all SELECT 'G002' 
union all SELECT 'G011'  





select * from @t 
order by cast(SUBSTRING(Number, 1, 
case when patindex('%[^0-9]%',Number) > 0 then patindex('%[^0-9]%',Number) - 1 else LEN(Number) end) as int), Number 

o wählen/p

**Number** 
B004 
B006 
B008 
B018 
G001 
G002 
G011 
L001 
L010 
L011 
L011 
L012 
UG001 
UG011 
8 
17 
18 
0

Ich hatte etwas ähnliches, aber mit der Möglichkeit von Bindestrichen als führende Zeichen sowie nachstehende Leerzeichen. Dieser Code hat für mich funktioniert.

SELECT 
    my_column, 
    PATINDEX('%[^0-9]%',my_column) AS first_alpha_position, 
    CONVERT(INT, 
    CASE 
     WHEN PATINDEX('%[^0-9]%',my_column) = 0 OR PATINDEX('-%',my_column) = 1 
      THEN ABS(my_column) 
     ELSE SUBSTRING(my_column,1,PATINDEX('%[^0-9]%',my_column) -1) 
    END) AS numeric_value, 
    LTRIM(
     SUBSTRING(my_column,PATINDEX('%[^0-9]%',my_column),LEN(my_column)-PATINDEX('%[^0-9]%',my_column)+1) 
) AS alpha_chars 
FROM my_table 
ORDER BY numeric_value,alpha_chars 
Verwandte Themen