core icon indicating copy to clipboard operation
core copied to clipboard

Feature: Implement natural sort to all order by queries

Open Aybee opened this issue 8 years ago • 13 comments

MySQL scheint ja kein natural sort anzubieten. Hier ein einfaches Beispiel:

sort ASC:
Type 1
Type 11
Type 2

sort ASC natural:
Type 1
Type 2
Type 11

Das wirkt sich negativ auf viele Bereiche aus. Beispiele:

  • Die BE-Listenansicht sortiert nach ASC|DESC
  • Die Reihenfolge in den Filtern im FE
  • Die Reihenfolge in der HTML5 Liste der Tags im FE

An einer Stelle in einem Template habe ich erfolgreich einen Patch aufgesetzt indem ich vor der Ausgabe nochmal mit PHP sortiere.

// Sort options natural
$tmpArray = $this->options;
usort($tmpArray, function($a, $b) {
  return strnatcasecmp($a['value'], $b['value']);
});
$this->options = $tmpArray;

Ist das technisch möglich, dass man im Core direkt nach den Queries das Ergebnis nochmal per PHP sortiert um dann out of the box überall eine natürliche Sortierung erwarten zu können?

Aybee avatar Jan 26 '17 19:01 Aybee

eine generelle Implementierung ist nicht angebracht, da man über die Filterregel "Eig. SQL" auch die Sortierung beeinflussen kann - auch Sachen wie nach Wochentag sortieren

ORDER BY FIELD(<fieldname>, 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY', 'SUNDAY');

auch verschiedene "natürliche Sortierungen" sind per SQL möglich https://www.google.de/search?client=firefox-b-ab&q=mysql+natural+sort

von daher würde das m.E. nur für die FE-Filter Sinn ergeben (so wie Deine Frage im IRC) - und dafür gibt es ein Ticket https://github.com/MetaModels/core/issues/74

...als kleinen Workaround könntest Du in das "Filter-Subtemplate" z.B. Deiner Tags-Checkboxen gehen und hier das HTML neu (sortiert) schreiben - alle Einzeldaten liegen hier vor

zonky2 avatar Jan 26 '17 20:01 zonky2

Ach.. was habe ich über die alphabetische Sortierung von mysql schon geflucht...

  • ä nach a
  • ä nach ae
  • ä nach z

Wörterbuch-Sortierung, Telefonbuch-Sortierung und was es sonst noch so gibt. https://de.wikipedia.org/wiki/Deutsches_Alphabet

Nach Versuchen, es auf Kosten der Performance und der Paginierung in php zu lösen und Experimenten mit COLLATE in meinen sql-Statements hat sich dann rausgestellt das es doch lieber eine manuelle Sortierung sein sollte 😢 Für den speziellen Fall (Nummern am Ende) lässt sich sicher eine wilde ORDER BY Formulierung finden.

asaage avatar Jan 26 '17 21:01 asaage

Der aktuelle Fall sieht so aus:

Zielgruppen:

  • Erwachsene
  • Klasse 1 - 5
  • Klasse 11 - 13
  • Klasse 6 - 10
  • Senioren

Ich hatte auch schon gegoogelt aber die Lösungen welche ich mir angesehen hatte passten alle nicht. Ich müsste so etwas machen SELECT *, title(machwas mit title) as tmpTitle FROM tablename ORDER BY tmpTitle

In tmpTitle müssten dann aufeinanderfolgende Zahlen vorne mit Nullen ergänzt werden.

  • Klasse 0001 - 0005
  • Klasse 0011 - 0013
  • Klasse 0006 - 0010

Da weiß ich aber nicht, ob bzw. wie man sowas machen kann.

Die Sortierung stimmt bereits in der BE-Listenansicht nicht. Wenn ich das richtig verstanden habe, dann muss ich ein Item "Sortierung und Gruppierung..." für die BE-Eingabemaske erstellen und dieses kann ich nur auf ASC o. DESC einstellen. screen-2017-01-26_23-27-47

Auch in der BE-Eingabemaske stimmt die Sortierung nicht, und hier kann ich doch auch auch nur beim Attribut Tags (Mehrfachauswahl) das Feld auswählen, nachdem sortiert werden soll. screen-2017-01-26_23-32-50

Der Workaround fürs FE aus #74 hat bei mir erstmal nicht angeschlagen, ich melde mich dort nochmal, was ich falsch gemacht habe.

Zu den oben erwähnten BE-Ansichten kommt dann noch das FE mit den Filtern screen-2017-01-26_23-41-05

Und die Darstellung von Tags in der Liste, sowohl HTML5 als auch Text. screen-2017-01-26_23-42-36

Damit mein Auftrag erledigt werden kann, werde ich jetzt die Ausgabe im FE über Templates korrigieren. Im BE muss der Kunde erstmal damit leben, dass es keine natürliche Sortierung gibt. Wäre schön, wenn es da doch noch irgendwann ne Core-Lösung für geben würde.

Aybee avatar Jan 26 '17 22:01 Aybee

Sicher nicht 100%ig bulletproof aber solang die Zahlen nach dem ersten Leerzeichen kommen, sich Zahlenbereiche nicht überlappen und der Text bis zum ersten Leerzeichen für die Sortierung ausreicht kannst du es hiermit probieren: http://sqlfiddle.com/#!9/252a1/6/0

asaage avatar Jan 27 '17 00:01 asaage

@asaage Diese Seite scheint bei mir irgendwie nicht zu laufen. Hast du vielleicht mal einen Gist o.ä.?

Aybee avatar Jan 27 '17 10:01 Aybee

https://gist.github.com/asaage/efbbe85181878b6ae9d24610c52655e8

asaage avatar Jan 27 '17 12:01 asaage

@asaage Danke schön. Aber ich dachte an eine Lösung für den Core, welche sämtliche Situationen abdeckt. Werde also im FE mit PHP nachsortieren.

Aybee avatar Jan 29 '17 16:01 Aybee

Das Problem mit der nachträglichen Sortierung per php ist, dass es nur auf relativ kleine Datenbestände anwendbar (bzw sinnvoll) ist. In meinem Fall hatte ich über 1000 Datensätze und da wünscht man sich eine Lösung die auch paginierbar ist. Da das mittels LIMIT und OFFSET auf querry-ebene passiert sehe ich für eine allgemeingültige Lösung leider schwarz. Natsort -featurerequests bei mysql geistern schon seit 13 Jahren herum und ich seh das auch in mysql8 nicht kommen. Was wohl noch praktikabel wäre, ist eine Feld mit einem Sortierschlüssel in dein Modell einzufügen. Die komplette Spalte müsste dann bei jedem Update und Insert mit php-natsort neu berechnet werden. Die zur Verfügung stehenden Events sollten das eigentlich ermöglichen. Für Select's bliebe dann auf jeden Fall alles wie gehabt bzgl Paginierung und Performance.

asaage avatar Jan 29 '17 19:01 asaage

Ah, gute Idee. Also z.B. mit nem onsave_callback diese zusätzliche Spalte aufbereiten? Ne Spalte sorting ist default ja schon vorhanden.

In der neuen mariaDB soll wohl ein search replace mit regex möglich sein. Dann könnte man auch sone Lösung wie z.B. Zahlen nach links mit 0 aufzufüllen umsetzen.

Aybee avatar Jan 29 '17 20:01 Aybee

Dachte die Spalte sorting gibts nur, wenn man manuelle Sortierung aktiviert hat aber die könnte man wohl auch nehmen. Ansonsten genau wie du sagst: im onsave_callback eine separate Spalte aufbereiten..

asaage avatar Jan 29 '17 21:01 asaage

Ja, sorting ist bei mir in jeder Tabelle drin (8 Stück). Alle mit dem Inhalt 0.

Aybee avatar Jan 29 '17 21:01 Aybee

Stimmt bei mir auch... zumindest im Schema, aber bei der Attributauswahl für die Sortierung ist es nicht verfügbar. Es wird dann wohl genommen, wenn man den Haken bei manuell setzt. Könnte Verwirrung stiften wenn man sich nach nem Jahr nochmal in die Modulkonfiguration begibt.

asaage avatar Jan 29 '17 21:01 asaage

Korrekt: sorting wird zB bei manueller Sortierung verwendet - aber auch bei hierarchischen Anzeigen

Aber vorhanden ist die Spalte immer!

zonky2 avatar Feb 05 '18 20:02 zonky2