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

Dieses Thema im Forum "Datenbanksysteme für das Web" wurde erstellt von maceis, 17.01.2006.

  1. maceis

    maceis Thread Starter MacUser Mitglied

    Beiträge:
    16.645
    Zustimmungen:
    596
    MacUser seit:
    24.09.2003
    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
     
  2. maceis

    maceis Thread Starter MacUser Mitglied

    Beiträge:
    16.645
    Zustimmungen:
    596
    MacUser seit:
    24.09.2003
    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.
     
  3. wegus

    wegus MacUser Mitglied

    Beiträge:
    15.039
    Zustimmungen:
    1.316
    MacUser seit:
    13.09.2004
    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 ...
    
     
  4. maceis

    maceis Thread Starter MacUser Mitglied

    Beiträge:
    16.645
    Zustimmungen:
    596
    MacUser seit:
    24.09.2003
    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.
     
  5. wegus

    wegus MacUser Mitglied

    Beiträge:
    15.039
    Zustimmungen:
    1.316
    MacUser seit:
    13.09.2004
    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 )
     
  6. maceis

    maceis Thread Starter MacUser Mitglied

    Beiträge:
    16.645
    Zustimmungen:
    596
    MacUser seit:
    24.09.2003
    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 ;).
     
  7. maceis

    maceis Thread Starter MacUser Mitglied

    Beiträge:
    16.645
    Zustimmungen:
    596
    MacUser seit:
    24.09.2003
    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.
     
Die Seite wird geladen...

Diese Seite empfehlen