Art string als Zahl in sql server
Habe ich eine Spalte, die Daten enthält wie dieses. Striche zeigen an mehreren Kopien der gleichen Rechnung und müssen diese in aufsteigender Reihenfolge sortiert werden
790711
790109-1
790109-11
790109-2
ich habe zu Sortieren (in aufsteigender Reihenfolge) von dieser Nummer, aber da dies ein varchar-Feld sortiert in alphabetischer Reihenfolge, wie diese
790109-1
790109-11
790109-2
790711
um dieses Problem zu beheben ich habe versucht, ersetzen Sie den Gedankenstrich (- ) mit leeren und dann Gießen Sie es als Zahl und dann die Sortierung auf, dass
select cast(replace(invoiceid,'-','') as decimal) as invoiceSort...............order by invoiceSort asc
dies ist zwar besser und ordnet so
invoiceSort
790711 (790711) <-----this is wrong now as it should come later than 790109
790109-1 (7901091)
790109-2 (7901092)
790109-11 (79010911)
Jemand schlug vor, zu mir zu split-Rechnung-id auf dem - (Bindestrich ) und um auf die 2 Teile aufgeteilt
wie=====> order by split1 asc,split2 asc (790109,1)
welche arbeiten würde ich denken, aber wie sollte ich das aufteilen der Spalte.
Den verschiedenen split-Funktionen auf der internet-sind diejenigen, die eine Tabelle zurückgeben, während in diesem Fall würde ich die Skalare Funktion.
Gibt es andere Ansätze, die verwendet werden können? Die Daten im grid und der grid-Ansicht nicht unterstützt Sortieren nach 2 Spalten standardmäßig ( kann ich umsetzen, es aber nicht 🙂 ) also, wenn einer einfacheren Ansätze sind da, ich wäre sehr nett.
BEARBEITEN : vielen Dank für all die Antworten. Während jede Antwort richtig ist, die ich gewählt habe, die Antwort, die mir erlaubte, zu integrieren, und diese Spalten in der GridView-Sortierung mit minimalen re-factoring des sql-Abfragen.
- Ich denke, das ausführlich zeigt, warum Ihre gespeicherten Werte sollten sich ändern....
- Warum willst du 790109-11 zu kommen, bevor 790109-2?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vernünftige Nutzung von
REVERSE
,CHARINDEX
, undSUBSTRING
Holen uns was wir wollen. Benutzt habe ich hoffentlich selbsterklärenden Spalten-Namen in meinem code unten, um zu veranschaulichen, was Los ist.Einrichten-Beispiel Daten:
Beispieldaten:
Und hier ist der code. Ich habe ein nagendes Gefühl, die letzten Ausdrücke vereinfacht werden könnte.
Ausgabe:
Beachten Sie, dass alles, was Sie wirklich brauchen, ist die
ORDER BY
Klausel, der rest ist nur zu zeigen, meine Arbeit, und der geht so:int
. Glücklicherweise erhalten wir eine Pause von SQL Server, die diese Umwandlung gibt null für eine leere Zeichenfolge.ORDER BY
(die Zahl ohne kleben) und dann von (der numerische Wert des zu kleben). Dies ist die Letzte Bestellung, die wir anstreben.Der code wäre übersichtlicher, wenn SQL Server erlaubt uns zu sagen
SUBSTRING(value, start)
um die Zeichenfolge beginnend an diesem Punkt, aber es funktioniert nicht, so müssen wir sagenSUBSTRING(value, start, LEN(value))
viel.Versuchen Sie, diese one -
- Abfrage:
Ausgabe:
Versuchen, diese
SQLFiddle Demo
Obige Abfrage verwendet zwei case-Anweisungen
Detaillierte Verständnis prüfen Sie die unten SQLfiddle
SQLFiddle Detaillierte Demo
Verwenden ODER 'CHARINDEX'
Um durch jeden Teil getrennt, ist der einfachste und zuverlässigste Weg zu gehen, warum andere Ansätze? Werfen Sie einen Blick auf diese einfache Abfrage.
Viele gute Antworten hier, aber ich denke, das könnten die meisten kompakten order by-Klausel wirksam ist:
Demo: - SQL Fiddle
Hinweis, ich habe das '790709' - version auf meinem test, da einige der hier aufgeführten Methoden sind nicht die Behandlung der no-suffix version kleiner als die mit-suffix-Versionen.
Wenn Ihr invoiceID in der Länge variiert werden, vor dem '-' ist, dann würden Sie brauchen:
Demo mit unterschiedlichen Längen vor dem Bindestrich: SQL Fiddle
Meine version:
Implementieren Sie diese als neue Spalte in Ihre Tabelle:
Eine Möglichkeit ist die split
InvoiceId
in seine Teile, und dann Sortieren Sie die Teile. Hier habe ich eine abgeleitete Tabelle verwenden, aber es könnte getan werden, mit einem CTE oder eine temporäre Tabelle.In der oben
InvoiceId1
undInvoiceId2
sind die TeileInvoiceId
. Die äußerenselect
enthält die Teile, aber nur für Demo-Zwecke - Sie brauchen nicht, dies zu tun in Ihrem wählen.Die abgeleitete Tabelle (die innere
select
) packt dieInvoiceId
sowie die Bauteile. Die Weise, die es funktioniert, ist dies:InvoiceId
,InvoiceId1
enthält der erste Teil der Nummer undInvoiceId2
enthält die zweite.InvoiceId1
leer und derInvoiceId2
enthält die gesamte Anzahl.Zweiten Fall oben (ohne Bindestrich) ist nicht optimal, da im Idealfall
InvoiceId1
enthalten würde, die Anzahl und dieInvoiceId2
leer wäre. Um die innere select-optimal funktionieren würde, verringern die Lesbarkeit des wählen Sie. Ich entschied mich für die nicht optimale, besser lesbar Ansatz, da ist es gut genug, um für die Sortierung.Dies ist der Grund, warum die
ORDER BY
Klausel tests für die Länge - es muss behandeln die beiden Fälle oben.Demo auf SQL Fiddle
Brechen die Art in zwei Abschnitte:
SQL Fiddle
MS SQL Server 2008-Schema-Setup:
Abfrage 1:
Ergebnisse:
Versuchen: