Humanisierte oder natürliche Nummernsortierung von gemischten Wort- und Nummernfolgen
Folgend aufdiese Frage durchSivaram ChintalapudiIch bin daran interessiert, ob es praktisch in PostgreSQL zu tun istnatürliche - oder "humanisierte" - Sortierung "von Zeichenfolgen, die eine Mischung aus mehrstelligen Zahlen und Wörtern / Buchstaben enthalten. Es gibt kein festes Muster von Wörtern und Zahlen in den Zeichenfolgen, und es kann mehr als eine mehrstellige Zahl in einer Zeichenfolge geben.
Der einzige Ort, an dem ich dies routinemäßig gesehen habe, ist der Finder des Mac OS, der Dateinamen mit gemischten Zahlen und Wörtern sortiert, wobei "20" nach "3" und nicht davor "20" steht.
Die gewünschte Kollatierungsreihenfolge würde durch einen Algorithmus erzeugt, der jede Zeichenfolge an den Buchstaben-Zahlen-Grenzen in Blöcke aufteilt und dann jeden Teil ordnet, wobei Buchstabenblöcke mit normaler Kollatierung und Zahlenblöcke als Ganzzahlen für Kollatierungszwecke behandelt werden. So:
'AAA2fred'
würde werden('AAA',2,'fred')
und'AAA10bob'
würde werden('AAA',10,'bob')
. Diese können dann beliebig sortiert werden:
regress=# WITH dat AS ( VALUES ('AAA',2,'fred'), ('AAA',10,'bob') )
regress-# SELECT dat FROM dat ORDER BY dat;
dat
--------------
(AAA,2,fred)
(AAA,10,bob)
(2 rows)
Im Vergleich zur üblichen Sortierung der Zeichenfolgen:
regress=# WITH dat AS ( VALUES ('AAA2fred'), ('AAA10bob') )
regress-# SELECT dat FROM dat ORDER BY dat;
dat
------------
(AAA10bob)
(AAA2fred)
(2 rows)
Der Datensatzvergleichsansatz verallgemeinert sich jedoch nicht, da Pg ROW (..) -Konstrukte oder Datensätze mit ungleicher Anzahl von Einträgen nicht vergleicht.
Angesichts der Beispieldatenin diesem SQLFiddle Die Standardkollatierung en_AU.UTF-8 ergibt die Reihenfolge:
1A, 10A, 2A, AAA10B, AAA11B, AAA1BB, AAA20B, AAA21B, X10C10, X10C2, X1C1, X1C10, X1C3, X1C30, X1C4, X2C1
aber ich möchte:
1A, 2A, 10A, AAA1BB, AAA10B, AAA11B, AAA20B, AAA21B, X1C1, X1C3, X1C4, X1C10, X1C30, X2C1, X10C10, X10C2
Ich arbeite zur Zeit mit PostgreSQL 9.1, aber Vorschläge, die nur 9.2 betreffen, wären in Ordnung. Ich bin an Ratschlägen interessiert, wie man eine effiziente Methode zur Aufteilung von Zeichenfolgen erreicht und wie man dann die resultierenden Aufteilungsdaten in der beschriebenen abwechselnden Sortierung von Zeichenfolgen und Zahlen vergleicht. Oder natürlich bei ganz anderen und besseren Ansätzen, bei denen keine Aufteilung der Zeichenfolgen erforderlich ist.
PostgreSQL scheint keine Komparatorfunktionen zu unterstützen, andernfalls könnte dies mit einem rekursiven Komparator und ähnlichem relativ einfach geschehenORDER USING comparator_fn
und eincomparator(text,text)
Funktion. Leider ist diese Syntax imaginär.
Aktualisieren: Blogbeitrag zum Thema.