Sortierung
Dominik Schäfer
- datenbank
Gibt es eine Möglichkeit, SQL über zwei Spalten gleichzeitig sortieren zu lassen?
SELECT * FROM persons WHERE person_birth LIKE '%-01-%' OR person_death LIKE '%-01-%' ORDER BY SUBSTRING(person_birth,6) ASC
Die Datenbank-Felder "person_birth" und "person_death" sind jeweils im Datumsformat, und ich möchte alle Datensätze, bei denen eines von beiden im Januar liegt, sortiert nach Tagen, nicht nach Jahren, deshalb der Substring.
Und zwar eben so sortiert, daß die jeweils andere, nicht im Januar liegende Spalte ignoriert wird und quasi eine virtuelle zusammengefasste Spalte sortiert wird.
Ist das irgendwie innerhalb eines SQL-Statements möglich, oder muß ich das nachträglich in PHP lösen?
Hallo,
Gibt es eine Möglichkeit, SQL über zwei Spalten gleichzeitig sortieren zu lassen?
Du kannst mehrere Sortierkriterien durch Komma getrennt in die order by Klausel aufnehmen. Sortiert wird dann zuerst nach der Bedingung an der ersten Stelle, bei Gleichheit nach der zweiten usw.
Grüße
Marcus
Hallo Dominik,
Gibt es eine Möglichkeit, SQL über zwei Spalten gleichzeitig sortieren zu lassen?
ja selbstverständlich, siehe Marcus.
SELECT * FROM persons WHERE person_birth LIKE '%-01-%' OR person_death LIKE '%-01-%' ORDER BY SUBSTRING(person_birth,6) ASC
Die Datenbank-Felder "person_birth" und "person_death" sind jeweils im Datumsformat,
Was verstehst Du unter "Datumsformat"? Ist der Datentyp der Spalte einer der Datumstypen, z.B. DATETIME oder DATE?
und ich möchte alle Datensätze, bei denen eines von beiden im Januar liegt, sortiert nach Tagen, nicht nach Jahren, deshalb der Substring.
Warum SUBSTRING(), wenn es Datumsfunktionen gibt, die z.B. den Monat herausfiltern können. Welche es gibt, hängt von Deinem Datenbankmanagementsystem ab. MONTH() anzuwenden - so vorhanden - ist meiner Meinung nach die bessere und intuitivere Idee.
Und zwar eben so sortiert, daß die jeweils andere, nicht im Januar liegende Spalte ignoriert wird und quasi eine virtuelle zusammengefasste Spalte sortiert wird.
Ist das irgendwie innerhalb eines SQL-Statements möglich,
Prinzipiell ja, da SQL auch ein IF-Statement bietet. Mittels dieser kannst Du eine solche Sortierspalte erstellen. Du musst Deine Aufgabenstellung noch ein wenig präzisieren. Welche Reihenfolge gilt, wenn beide Datumsangaben in den Januar fallen, welche Angabe hat in diesem Fall Priorität.
Freundliche Grüße
Vinzenz
Hi Vinzenz,
erstmal vielen Dank für Deine Antwort!
ja selbstverständlich, siehe Marcus.
Daß das so geht, weiß ich natürlich - aber es soll ja eben nicht erst nach Spalte 1, danach nach Spalte 2 sortieren, sondern beide zusammenfassen.
Was verstehst Du unter "Datumsformat"? Ist der Datentyp der Spalte einer der Datumstypen, z.B. DATETIME oder DATE?
Sie sind im Typ DATE, also "2006-01-27"
Prinzipiell ja, da SQL auch ein IF-Statement bietet. Mittels dieser kannst Du eine solche Sortierspalte erstellen. Du musst Deine Aufgabenstellung noch ein wenig präzisieren. Welche Reihenfolge gilt, wenn beide Datumsangaben in den Januar fallen, welche Angabe hat in diesem Fall Priorität.
Im Idealfall wäre die Abfrage so gebaut, daß wenn beide Daten im Januar liegen, der Datensatz zweimal gefunden und einsortiert wird. Wenn das nicht geht hätte das Geburtsdatum Priorität.
Danke sehr!
Dominik
Hallo Dominik,
Was verstehst Du unter "Datumsformat"? Ist der Datentyp der Spalte einer der Datumstypen, z.B. DATETIME oder DATE?
Sie sind im Typ DATE, also "2006-01-27"
prima, da solltest Du unbedingt eine Datums- und Zeitfunktion wie MONTH() statt SUBSTR() verwenden, d.h. extrahiere den Monat mit
MONTH(person_birth) bzw. MONTH(person_death)
Im Idealfall wäre die Abfrage so gebaut, daß wenn beide Daten im Januar liegen, der Datensatz zweimal gefunden und einsortiert wird. Wenn das nicht geht hätte das Geburtsdatum Priorität.
Dein Idealfall ist möglich, nur nicht mit Deinem Statement. Als einfachster Weg fällt mir im Augenblick UNION ein, das Deine Sortierung gerade mit erledigen kann.
UNION wird von allen üblichen Datenbankmanagementsystemen (DBMS) unterstützt, einzige mir bekannte Ausnahme ist MySQL, Version 3.x. Deswegen wäre es sehr hilfreich, wenn Du schreibst, welches DBMS in welcher Version Du benutzt.
Für MySQL könnte Deine Abfrage in etwa so aussehen, siehe dazu auch UNION:
(SELECT
spalte1,
-- weitere Spalten, die Du haben willst
DAY(person_birth) AS special_day, -- die Sortierspalte!
'Geburt' AS Event
FROM persons
WHERE MONTH(person_birth) = 1)
UNION
(SELECT
spalte1,
-- weitere Spalten in exakt gleicher Reihenfolge
DAY(person_death), -- hier ist kein Spaltenname erforderlich, da
-- dieser durch die erste Abfrage vorgegeben ist
'Tod'
FROM persons
WHERE MONTH (person_death) = 1)
ORDER BY special_day
d.h. Ermittle in der ersten Abfrage alle Personen, die im Januar geboren sind, in der zweiten alle Personen, die im Januar gestorben sind, verbinde die Ergebnisse zu einer Gesamtergebnismenge, die Du nach dem Tag im Monat sortieren lässt. Den Aufwand dieser Abfrage solltest Du Dir mal mit EXPLAIN ausgeben lassen (bzw. ähnlichen Tools in anderen DBMS).
Es ist übrigens fast immer eine gute Idee, die Spalten, die man im Ergebnis benötigt einzeln aufzuführen und nicht einfach SELECT *
zu schreiben.
Freundliche Grüße
Vinzenz
Das ist absolut perfekt, vielen Dank! Ich hatte in der Zwischenzeit schon die suboptimale Variante hinbekommen, aber das ist so viel besser!
Hab mal den Link angehängt, wenn Du Dir das Ergebnis anschauen möchtest.
Herzlichen Dank!!!
Dominik