SQL für die Bestellung nach Nummer - 1,2,3,4 usw. anstelle von 1,10,11,12

85

Ich versuche, nach einer Zahlenspalte in meiner Datenbank mit den Werten 1-999 zu bestellen

Wenn ich benutze

ORDER_BY registration_no ASC

Ich bekomme….

1
101
102
103
104
105
106
107
108
109
11
110
Etc…

Es scheint also nach der ersten Ziffer im Gegensatz zur Nummer zu ordnen.

Weiß jemand, welches SQL zu verwenden ist, wenn ich dies nach Wert sortieren möchte? Also 1,2,3,4,5,6etc.

Konnor262
quelle
11
Ihre Spalte ist vom Typ varchar, aufgrund dessen Sie diesem Verhalten ausgesetzt sind.
Meherzad
Was ist der Datentyp der Spalte "register_no"?
Praveen Prasannan
9
Verwenden Sie order by registration_no + 0 asc, um Ihr Problem zu lösen.
Meherzad
10
Sie sollten niemals Zahlen in einer Zeichenspalte speichern. Ihr Problem ist eine direkte Folge dieses Fehlers.
a_horse_with_no_name
Meine Spalte ist Varchar und die von mir gespeicherten Daten sind Klasse 10 / Klasse 9 / Klasse 8. Jetzt kommt Klasse 10 vor Klasse 8. Wie löse ich das, ohne für eine display_order-Spalte arbeiten zu müssen?
Vishnoo Rath

Antworten:

138

Eine Möglichkeit, nach positiven ganzen Zahlen zu ordnen, wenn sie als gespeichert sind varchar, besteht darin, zuerst nach der Länge und dann nach dem Wert zu ordnen:

order by len(registration_no), registration_no

Dies ist besonders nützlich, wenn die Spalte möglicherweise nicht numerische Werte enthält.

Hinweis: In einigen Datenbanken wird möglicherweise die Funktion zum Abrufen der Länge einer Zeichenfolge length()anstelle von aufgerufen len().

Gordon Linoff
quelle
1
Dies funktioniert nicht in allen Fällen. Fälle, die nicht funktionieren, sind Mischungen ganzer Zahlen mit; negative Zahlen, Zahlen mit führenden Nullen, Zahlen mit Brüchen und Wörter und Zahlen kombiniert.
WonderWorker
10
@ Knickerless-Noggins. . . Lesen Sie den ersten Satz der Antwort. Ich denke es ist ziemlich klar.
Gordon Linoff
@GordonLinoff bestellt zweimal nach derselben Spalte ist nicht CPU- und speicherintensiv?
LoneStar
@ Achyuth. . . Die Anzahl der Tasten in einem order byhat wenig Einfluss auf die Leistung.
Gordon Linoff
1
Verwenden Sie für Oracle SQL length()anstelle vonlen()
Stevoisiak
61
ORDER_BY cast(registration_no as unsigned) ASC

konvertiert den Wert explizit in eine Zahl. Eine andere Möglichkeit, dasselbe zu erreichen, wäre

ORDER_BY registration_no + 0 ASC

Dies erzwingt ein implizites Gespräch.

Eigentlich sollten Sie die Tabellendefinition überprüfen und ändern. Sie können den Datentyp so ändern, dass er Ihnen intgefällt

ALTER TABLE your_table MODIFY COLUMN registration_no int;
Jürgen d
quelle
13

Wenn Sie SQL Server verwenden:

ORDER_BY cast(registration_no as int) ASC
IPOSTEDONCE
quelle
3
ORDER_BY cast(registration_no as unsigned) ASC

gibt das gewünschte Ergebnis mit Warnungen.

Daher besser zu gehen

ORDER_BY registration_no + 0 ASC

für ein sauberes Ergebnis ohne SQL-Warnungen.

Priyanka
quelle
2

Ich gehe davon aus, dass Ihr Spaltentyp STRING (CHAR, VARCHAR usw.) ist und die Sortierprozedur ihn als Zeichenfolge sortiert. Was Sie tun müssen, ist, den Wert in einen numerischen Wert umzuwandeln. Wie das geht, hängt vom verwendeten SQL-System ab.


quelle
1

Manchmal haben Sie einfach keine Wahl, Zahlen mit Text gemischt zu speichern. In einer unserer Anwendungen macht der Website-Host, den wir für unsere E-Commerce-Website verwenden, Filter dynamisch aus Listen. Es gibt keine Möglichkeit, nach einem anderen Feld als dem angezeigten Text zu sortieren. Wenn wir Filter wollten, die aus einer Liste erstellt wurden, die Dinge wie 2 "bis 8" 9 "bis 12" 13 "bis 15" usw. enthielt, brauchten wir sie, um 2-9-13 zu sortieren, nicht 13-2-9, wie es sein wird, wenn Lesen der numerischen Werte. Daher habe ich die SQL Server-Replikationsfunktion zusammen mit der Länge der längsten Nummer verwendet, um kürzere Nummern mit einem führenden Leerzeichen aufzufüllen. Jetzt werden 20 nach 3 sortiert und so weiter.

Ich habe mit einer Ansicht gearbeitet, die mir die minimalen und maximalen Längen, Breiten usw. für den Elementtyp und die Klasse angibt. Hier ist ein Beispiel dafür, wie ich den Text erstellt habe. (LB n Low und LB n High sind das Low- und High-Ende der 5 Längenklammern.)

REPLICATE(' ', LEN(LB5Low) - LEN(LB1High)) + CONVERT(NVARCHAR(4), LB1High) + '" and Under' AS L1Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB2Low)) + CONVERT(NVARCHAR(4), LB2Low) + '" to ' + CONVERT(NVARCHAR(4), LB2High) + '"' AS L2Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB3Low)) + CONVERT(NVARCHAR(4), LB3Low) + '" to ' + CONVERT(NVARCHAR(4), LB3High) + '"' AS L3Text,
REPLICATE(' ', LEN(LB5Low) - LEN(LB4Low)) + CONVERT(NVARCHAR(4), LB4Low) + '" to ' + CONVERT(NVARCHAR(4), LB4High) + '"' AS L4Text,
CONVERT(NVARCHAR(4), LB5Low) + '" and Over' AS L5Text
Joey Morgan
quelle
1

Ich mache lieber ein "PAD" für die Daten. MySql nennt es LPAD, aber Sie können sich daran arbeiten, dasselbe in SQL Server zu tun.

ORDER BY  REPLACE(STR(ColName, 3), SPACE(1), '0') 

Diese Formel liefert führende Nullen basierend auf der Spaltenlänge von 3. Diese Funktionalität ist in anderen Situationen außerhalb von ORDER BY sehr nützlich. Deshalb wollte ich diese Option bereitstellen.

Ergebnisse: 1 wird 001 und 10 wird 010, während 100 gleich bleibt.

SQLCodingIsFunnn
quelle
0

Dieses Problem liegt nur daran, dass Sie die Spalte im Datentyp CHAR, VARCHAR oder TEXT deklariert haben. Ändern Sie einfach den Datentyp in INT, BIGINT usw. Dies löst das Problem Ihrer benutzerdefinierten Bestellung.

Dev Rathi
quelle