[MySQL:] Bedingung für "ORDER BY"

maceis

maceis

Aktives Mitglied
Thread Starter
Dabei seit
24.09.2003
Beiträge
16.880
Reaktionspunkte
626
hallo zusammen,

kann man in einer Abfrage eine Bedingung für die Sortierung durch ORDER BY verwenden.

Etwa so:
SELECT .... IF feld1>=feld2 ORDER BY feld2 ELSE ORDER BY feld3

MySQL Version 4.1
 
Kaum postet man die Frage, findet man einen Lösungsansatz
Veilleicht kann es mal jemand brauchen.

Man kann Bedingungen in die SELECT Abfrage einbauen und diese dann zum Sortieren verwenden.

Code:
SELECT IF(feld1>=feld2,a,b) AS 'bedingung' ... ORDER BY bedingung,feld3,feld2
Entspricht nicht ganz der Beschreibung oben, aber damit kann man was basteln.

Falls jemand noch eine schlaue Idee hat, bitte posten.
 
Das sind keine Bedingungen sondern virtuelle Spalten einer DB!

Du kannst auch z.B. schreiben:

Code:
SELECT nettopreis, mwstbetrag, nettopreis+mwstbetrag AS 'bruttopreis' FROM preisliste ...

diese virtuellen Spalten können dann auch in ORDER BY-Klauseln verwendet werden. Manche SQL-Server erlauben statt des AS Schlüsselwortes auch die eingängigere Variante

Code:
SELECT nettopreis, mwstbetrag, bruttopreis=nettopreis+mwstbetrag FROM preisliste ...
 
wegus schrieb:
Das sind keine Bedingungen sondern virtuelle Spalten einer DB!
...
Schon klar, aber der Inhalt einer solchen virtuellen Spalte wird mit einer Bedingung definiert. Auf diesem Umweg, kann man eine (oder mehrere) zusätzliche Sortierebenen einführen.

Konkret geht es bei mir um eine Tabelle in der Termine für Rabattaktionen gespeichert sind, die ich gleich mit der SELECT Abfrage richtig sortieren möchte, was gar nicht so einfach ist.

Für manche Aktionen gibt es einen Starttermin und einen Endtermin.
andere Aktionen haben je zwei Start- und Endtermine.
Die Termine können sich auf unterschiedliche Art überschneiden.

Vereinfacht kann man von 5 Feldern ausgehen aktion (TEXT), start1 (DATE), ende1 (DATE), start2(DATE), ende2(DATE).

Sortiert werden soll nach den start Feldern, wobei start1 nur dann berücksichtig werden soll, wenn ende1 >=now().
Dass nur Datensätze ausgewählt werden, bei denen (ende1>=now() AND ende2>=now()) gilt ist eh klar.

Mein bisheriger Ansatz sieht so aus, funktioniert aber noch nicht ganz wunschgemäß:
Code:
$sql = qq/SELECT
IF (ende1>=now(),1,2) AS 'bed',
aktion,  # TEXT
start1,  # DATE
ende1,  # DATE
start2,  # DATE
,  # DATE
    [...]
FROM aktionen, beschreibungen.$language
WHERE [...]
AND (ende1>= now() OR ende2 >=now()) # min ein Termin noch nicht abgelaufen
ORDER BY bed,start1,start2
/

Ein Problem gibt es bei Datensätzen für die gilt (ende1<now()) UND (start2<start1) von anderen Datensätzen mit (ende1>=now().
Die werden nämlich dann aufgrund der Bedingung nach hinten geschoben und somit nicht korrekt einsortiert.

Ich hoffe, ich hab das jetzt so beschrieben, dass man es versteht ;).
Wenn Du (oder jemand anders) einen besseren Lösungsansatz wissen, bitte posten.
 
Eine (andere) Lösung in einem Rutsch fällt mir gerade auch nicht ein.
Der Intuition und Wartbarkeit folgend würde ich mit temporären Tabellen und mehrfachen Abbildungen arbeiten. Dieser scheinbare Umweg kommt einem später bei Erweiterungen meist zugute. Auch muß man nach redundanten Prüfungen Ausschau halten. So impliziert start>now() ja automatisch das ende1>now() ist und muß gar nicht geprüft werden ( Es sei denn das Ende läge vor dem Start :D )
 
Ja, sortiert werden soll ja nach startn Terminen, während die enden Termine für die Auswahl verwendet werden.
Ich glaube ich hab da gerade eine Idee ;).
 
Mann ist das einfach ;) (wenn man erst mal kapiert hat, worum es geht;

Code:
$sql = qq/SELECT
IF (ende1>=now(),ende1,ende2) AS 'bed',
aktion,  # TEXT
start1,  # DATE
ende1,  # DATE
start2,  # DATE
,  # DATE
    [...]
FROM aktionen, beschreibungen.$language
WHERE [...]
AND (ende1>= now() OR ende2 >=now()) # min ein Termin noch nicht abgelaufen
ORDER BY bed,start1,start2
/
Jetzt wird für Aktionen, bei denen ende1 noch nicht erreicht ist start1 zur Sortierung verwendet und für die bei denen ende1 bereits vorbei ist start2.

Das einzige was man jetzt noch beachten muss, ist, dass man im CGI Skript die Ausgabe von bed entsorgt.

Danke für das feedback - hat mir auf die Sprünge geholfen.
 
Zurück
Oben Unten