Sortierung der Zeichenfolge als Zahl in SQL Server

8

Ich habe eine Spalte, die solche Daten enthält. Bindestriche geben Mehrfachkopien derselben Rechnung an, und diese müssen in aufsteigender Reihenfolge sortiert sein.

%Vor%

Ich muss es in aufsteigender Reihenfolge nach dieser Zahl sortieren, aber da dies ein varchar-Feld ist, sortiert es in alphabetischer Reihenfolge wie folgt

%Vor%

Um dies zu beheben, habe ich versucht, das - (Bindestrich) mit leer zu ersetzen und es dann als Zahl umzuwandeln und dann darauf zu sortieren

%Vor%

Während das besser ist und sortiert so

%Vor%

Jemand schlug mir vor, die Rechnungs-ID auf dem - (Bindestrich) aufzuteilen und auf den zwei Teilen

zu bestellen

wie ===== & gt; order by split1 asc,split2 asc (790109,1)

was funktionieren würde ich denke aber wie würde ich die Spalte aufteilen.

Die verschiedenen Split-Funktionen im Internet sind diejenigen, die eine Tabelle zurückgeben, während ich in diesem Fall eine Skalarfunktion benötige.

Gibt es noch andere Ansätze, die verwendet werden können? Die Daten werden in der Grid-Ansicht angezeigt und die Grid-Ansicht unterstützt standardmäßig nicht die Sortierung auf 2 Spalten (ich kann es jedoch implementieren :)). Wenn einfachere Ansätze vorhanden sind, wäre ich sehr nett.

BEARBEITEN : Danke für alle Antworten. Während jede Antwort korrekt ist, habe ich die Antwort gewählt, die es mir erlaubt hat, diese Spalten in die GridView-Sortierung mit minimalem Re-Faktoring der SQL-Abfragen zu integrieren.

    
Pankaj Kumar 01.05.2013, 10:16
quelle

9 Antworten

3

Vernünftige Verwendung von REVERSE , CHARINDEX und SUBSTRING , kann uns erreichen, was wir wollen. Ich habe hoffentlich erläuternde Spaltennamen in meinem Code unten verwendet, um zu illustrieren, was vor sich geht.

Einrichten von Beispieldaten:

%Vor%

Beispieldaten:

%Vor%

Und hier ist der Code. Ich habe ein nörgelndes Gefühl, die letzten Ausdrücke könnten vereinfacht werden.

%Vor%

Ausgabe:

%Vor%

Beachten Sie, dass Sie wirklich nur die ORDER BY -Klausel brauchen, der Rest ist nur, um meine Arbeit zu zeigen, was so aussieht:

  • Kehren Sie die Zeichenfolge um, suchen Sie den Bindestrich, rufen Sie die Teilzeichenfolge nach dem Bindestrich ab, kehren Sie diesen Teil um: Dies ist die Zahl ohne Affix
  • Die Länge von (die Zahl ohne Affix) sagt uns, wie viele Zeichen von Anfang an fallen gelassen werden müssen, um den Affix einschließlich des Bindestrichs zu erhalten. Legen Sie ein zusätzliches Zeichen ab, um nur den numerischen Teil zu erhalten, und konvertieren Sie dieses in int . Glücklicherweise erhalten wir eine Pause von SQL Server, da diese Konvertierung Null für eine leere Zeichenfolge liefert.
  • Schließlich haben wir diese zwei Teile, wir einfach ORDER BY (die Zahl ohne Affix) und dann durch (der numerische Wert des Affix). Dies ist die letzte Reihenfolge, die wir suchen.

Der Code wäre prägnanter, wenn SQL Server uns erlauben würde, SUBSTRING(value, start) zu sagen, um den String ab diesem Punkt zu bekommen, aber nicht, also müssen wir SUBSTRING(value, start, LEN(value)) viel sagen.

    
AakashM 06.06.2013, 09:36
quelle
4

Probieren Sie diese -

Abfrage:

%Vor%

Ausgabe:

%Vor%     
Devart 07.06.2013 06:26
quelle
3

Versuchen Sie es

%Vor%

SQLFiddle-Demo

Die obige Abfrage verwendet zwei Case-Anweisungen

  1. Sortiert den ersten Teil von Invoiceid 790109-1 (zB: 790709)
  2. Sortiert den zweiten Teil von Invoiceid nach dem Teilen mit '-' 790109-1 (zB: 1)

Für ein detailliertes Verständnis überprüfen Sie die folgende SQLFiddle

detaillierte SQLFiddle-Demo

ODER verwenden Sie 'CHARINDEX'

%Vor%     
bvr 07.06.2013 10:23
quelle
2

Reihenfolge nach jedem Teil separat ist der einfachste und zuverlässigste Weg zu gehen, warum nach anderen Ansätzen suchen? Werfen Sie einen Blick auf diese einfache Abfrage.

%Vor%     
Khanh TO 09.06.2013 06:18
quelle
2

Viele gute Antworten hier, aber ich denke, dass dies die kompakteste Reihenfolge nach Klausel ist, die effektiv ist:

%Vor%

Demo: - SQL Fiddle

Beachten Sie, dass ich die Version '790709' zu meinem Test hinzugefügt habe, da einige der hier aufgelisteten Methoden die No-Suffix-Version nicht als weniger als die With-Suffix-Versionen behandeln.

Wenn Ihre Rechnungs-ID unterschiedlich lang ist, vor dem '-', dann benötigen Sie:

%Vor%

Demo mit verschiedenen Längen vor dem Bindestrich: SQL Fiddle

    
Hart CO 09.06.2013 18:33
quelle
1

Meine Version:

%Vor%

Sie können dies als neue Spalte in Ihre Tabelle implementieren:

%Vor%     
Stoleg 06.06.2013 09:36
quelle
1

Eine Möglichkeit besteht darin, InvoiceId in seine Teile aufzuteilen und dann nach den Teilen zu sortieren. Hier verwende ich eine abgeleitete Tabelle, aber es könnte auch mit einem CTE oder einer temporären Tabelle gemacht werden.

%Vor%

Im obigen Beispiel sind InvoiceId1 und InvoiceId2 die Bestandteile von InvoiceId . Das äußere select enthält die Teile, aber nur zu Demonstrationszwecken - Sie müssen dies nicht bei der Auswahl tun.

Die abgeleitete Tabelle (das innere select ) erfasst das InvoiceId sowie die Komponenten. So funktioniert es:

  • Wenn in InvoiceId ein Bindestrich vorhanden ist, enthält InvoiceId1 den ersten Teil der Zahl und InvoiceId2 enthält den zweiten Teil.
  • Wenn kein Bindestrich vorhanden ist, ist InvoiceId1 leer und InvoiceId2 enthält die gesamte Zahl.

Der zweite obige Fall (kein Bindestrich) ist nicht optimal, weil idealerweise InvoiceId1 die Zahl enthalten würde und InvoiceId2 leer wäre. Um die innere Auswahl optimal arbeiten zu lassen, würde die Lesbarkeit der Auswahl verringert. Ich wählte den nicht optimalen, lesbareren Ansatz, da es gut genug ist, um das Sortieren zu ermöglichen.

Aus diesem Grund testet die ORDER BY -Klausel die Länge - sie muss die beiden obigen Fälle behandeln.

Demo bei SQL Fiddle

    
chue x 06.06.2013 14:34
quelle
1

Brechen Sie die Sortierung in zwei Abschnitte:

SQL Fiddle

MS SQL Server 2008 Schema-Setup :

%Vor%

Abfrage 1 :

%Vor% Ergebnisse :

%Vor%     
Steve Ford 11.06.2013 09:41
quelle
0

Versuchen:

%Vor%     
johndsamuels 01.05.2013 10:44
quelle