Oracle: Wie kann ich die Implementierung einer "natürlichen" order by in einer SQL-Abfrage?
e.g,
foo1
foo2
foo10
foo100
eher als
foo1
foo10
foo100
foo2
Update: kein Interesse bei der Codierung der Art selber zu machen (obwohl das in seinem eigenen Recht interessant), aber mit der Datenbank zu tun, die Art für mich.
- Jeff hat auch eine post auf dem Thema, mit mehr Ressourcen für andere Sprachen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Funktionen können Sie bei Ihrer order-by-Klausel. In diesem Fall
Sie teilen die nicht-numerische und numerische Teile der
Feld-und verwenden Sie Sie als zwei der ordnenden Kriterien.
Können Sie auch erstellen Sie einen funktionsbasierten index, dies zu unterstützen:
Benutze ich folgende Funktion nach 0-pad alle Sequenzen von Ziffern, kürzer als 10, die gefunden werden konnte, in den Wert, so dass die gesamte Länge jedes zu 10 Ziffern. Es ist kompatibel auch mit gemischten Sätze von Werten, die haben eine, viele oder keine der Sequenzen der Ziffern in Ihnen.
Beispiel:
Für kurze strings, die kleine Zahl der Numerik
Wenn die Anzahl der "Numerik" und die maximale Länge begrenzt sind, gibt es ein regexp-basierte Lösung.
Die Idee ist:
Annahmen:
lpad('1 ', 3000, '1 ')
wird scheitern tun nicht fit gepolsterte Numerik invarchar2(4000)
)Die folgende Abfrage ist optimiert für eine "kurz-Numerik" - Fall (siehe
*?
) und es dauert 0,4 Sekunden. Jedoch, wenn Sie verwenden diese Vorgehensweise, die Sie benötigen, vordefinieren Polsterung Länge."Clever" - Ansatz
Obwohl separate
natural_sort
Funktion kann praktisch sein, es ist eine wenig bekannte trick zu tun, die in reinem SQL.Grundgedanken:
02
bestellt wird zwischen1
und3
:regexp_replace(val, '(^|\D)0+(\d+)', '\1\2')
. Hinweis: dies kann dazu führen, "unerwartete" Sortierung von10.02
>10.1
(seit02
umgewandelt2
), jedoch gibt es keine einfache Antwort, wie Dinge wie10.02.03
sortiert werden sollen"
zu""
so dass text mit Anführungszeichen funktioniert'"'||regexp_replace(..., '([^0-9]+)', '","\1","')||'"'
xmltable
length(length(num))||length(num)||num
stattlpad(num, 10, '0')
als die letztere ist weniger kompakt und nicht unterstützt 11+ stellige zahlen.Hinweis:
Reaktionszeit ist so etwas wie 3-4 Sekunden für die Sortierung der Liste von 1000 zufälligen strings der Länge 30 (die Generierung der zufälligen Zeichenfolgen dauert 0.2 sec selbst).
Der wichtigste Zeitfaktor ist
xmltable
dass teilt text in Zeilen.Wenn Sie mit PL/SQL statt
xmltable
aufteilen, string in Zeilen, die Reaktionszeit verringert sich auf 0,4 Sek für 1000 Zeilen.Die folgende Abfrage führt die Natürliche Sortierung von 100 zufälligen alpha-numerischen strings (Hinweis: es produziert falsche Ergebnisse in Oracle 11.2.0.4 und es funktioniert in 12.1.0.2):
Den Spaß-Teil ist das
order by
ausgedrückt werden kann, ohne Unterabfragen, so ist es ein handliches Werkzeug, um Ihren Rezensent verrückt (es funktioniert in beide 11.2.0.4 und 12.1.0.2):