PostgreSQL, UM DURCH Problem - die Natürliche Art
Ich habe eine Postgres ORDER BY
Problem mit der folgenden Tabelle:
em_code name
EM001 AAA
EM999 BBB
EM1000 CCC
Einfügen einen neuen Datensatz in der Tabelle,
- Ich wählen Sie den letzten Datensatz mit
SELECT * FROM employees ORDER BY em_code DESC
- Strip Alphabete von em_code usiging reg exp und speichern in
ec_alpha
- Besetzung der Neuverknüpfung Teil zu integer
ec_num
- Schrittweite von einem
ec_num++
- Pad mit ausreichend zeors und Präfix
ec_alpha
wieder
Wenn em_code
erreicht EM1000, den oben beschriebenen Algorithmus fehlschlägt.
Ersten Schritt zurück EM999 statt EM1000 und es wird wieder generieren EM1000 als neue em_code
brechen der unique key-Einschränkung.
Keine Ahnung, wie zu wählen Sie EM1000?
- Warum verwenden Sie nicht nur Folge?
- Warum nicht eine Sequenz? postgresql.org/docs/current/static/sql-createsequence.html
- Ach ein Klassiker. Regel eins für ein edvgestütztes Papier-Systeme, intelligente zahlen sind, sind dumm. setzen Sie em in einer Spalte ein Wert vom Typ int in die andere Sorte von beiden. Bauen Sie es wieder in eine id für die dummen Menschen, wenn Sie müssen.
- Brandstetter Dank für die Bearbeitungen
- Beachten Sie, dass der Ansatz, den Sie beschreiben, wird kläglich scheitern, wenn mehr als eine Transaktion gleichzeitig ist
INSERT
ing, es sei denn, SieLOCK TABLE
ersten. Bezüglich der Art, vielleicht finden Sie diese Frage sehr informativ.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Der Grund dafür ist, dass die Zeichenfolge sortiert alphabetisch (anstatt numerisch wie Sie es möchten) und 1 sortiert vor 9.
Man könnte es lösen wie diese:
Es wäre effizienter, fallen die redundante 'EM' von Ihrem
em_code
wenn Sie können, und speichern Sie eine ganze Zahl zu beginnen.Zusätzliche Antwort auf die Frage im Kommentar
Streifen, alle nicht-Ziffern aus einem string:
\D
ist der reguläre Ausdruck Klasse-Kürzel für "nicht-Ziffern".'g'
als 4. parameter der "Global" - Schalter auf anwenden, um die Ersatz zu jedem vorkommen der Zeichenfolge, nicht nur das erste mal.Also tausche ich jede nicht-Ziffer mit den leeren string destillieren ausschließlich Ziffern aus dem string.
EM
könnten gespeichert werden in einer anderen Spalte zum Beispiel, und beide Spalten deklariert werden könnte als Schlüssel für die Tabelle. Das würde auch erleichtern das einfügen neuer Zeile-Zeug.substring
?Einem Ansatz, den Sie ergreifen können, ist das erstellen einer
naturalsort
Funktion für diese. Hier ein Beispiel, geschrieben von Postgres-Legende RhodiumToad.Quelle: http://www.rhodiumtoad.org.uk/junk/naturalsort.sql
Verwenden Sie einfach die Funktion aufrufen, die in Ihrem Auftrag von:
Kommt das immer bis in den Fragen und in meiner eigenen Entwicklung, und ich schließlich müde von der knifflige Wege, dies zu tun. Ich schließlich brach und setzte es als eine PostgreSQL-Erweiterung:
https://github.com/Bjond/pg_natural_sort_order
Es ist kostenlos zu benutzen, MIT-Lizenz.
Im Grunde ist es nur normalisiert die Numerik (null pre-pending Numerik) innerhalb von Zeichenfolgen, so dass Sie können erstellen Sie eine Indexspalte für full-speed-Sortierung au naturel. Die readme erklärt.
Der Vorteil ist man kann ein trigger die Arbeit machen und nicht im code der Anwendung. Es wird berechnet auf der Maschine-Geschwindigkeit auf den PostgreSQL-server und Migrationen hinzufügen von Spalten zu einfach und schnell.
können Sie verwenden Sie einfach diese Zeile
"ORDER BY length(substring(em_code VON" [0-9]+')), em_code"
Darüber schrieb ich ausführlich in diesem Zusammenhang Frage:
Humanisierte oder Natürliche Zahl Sortierung von gemischten Wort-und-Anzahl-strings
(Ich bin dieses posting eine Antwort, als ein nützliches cross-reference nur, so ist es community-wiki).
Ich dachte über eine andere Möglichkeit, dies zu tun, verwendet weniger db-storage als Polsterung und spart Zeit als die Berechnung der on-the-fly.
https://stackoverflow.com/a/47522040/935122
Ich habe auch legte es auf GitHub
https://github.com/ccsalway/dbNaturalSort