suit: MySQL nach mehreren Feldern übergreifend sortieren.

Hallo,

ein kleines Problem bzw. eine Frage:

Wie kann ich mit MySQL in Abhängigkeit bestimmter Feldinhalte sortieren?

ID | foo | bar
---+-----+------
1  | aaa |
2  | ccc |
3  | ddd | zzz
3  | fff |
5  | ggg | bbb

Ich möchte folgende Tabelle nun nach foo und bar sortieren und zwar so, dass prinzipiell nach "foo" sortiert wird, die Feldinhalte von "foo" aber mit jenen von "bar" (wenn vorhanden) "überlagert" werden

Prinzipiell würde ich einfach beide Felder mit CONCAT zusammenhängen, in ein Alias schreiben und nach dem Alias sortieren.

SELECT CONCAT (bar, foo) as baz ORDER BY baz

Damit sollte ich als Ausgabe folgendes erhalten:

baz
------
aaa
bbbggg
ccc
fff
zzzddd

Für meinen Anwendungsfall würde dies wahrscheinlich ausreichen, wird aber vemutlich bei variablen Stringlängen zu abweichungen in der Reihenfolge kommen - oder täusche ich mich da?

Bzw. gibts dafür eine andere, bessere Möglichkeit?

  1. SELECT CONCAT (bar, foo) as baz ORDER BY baz

    Folgendes ist kürzer und geht auch, aber logisch dasselbe (wenn man von der Ausgabe absieht):

    SELECT id ORDER BY CONCAT(bar, foo)

    1. Hallo suit,

      SELECT CONCAT (bar, foo) as baz ORDER BY baz

      Folgendes ist kürzer und geht auch, aber logisch dasselbe (wenn man von der Ausgabe absieht):
      SELECT id ORDER BY CONCAT(bar, foo)

      Dein Beispiel ist nicht ausreichend spezifiziert. Sprich: es gibt keinen Fall, wo Deine Spezialsortierung greift. Außerdem sind bestimmte Randbedingungen nicht berücksichtigt, die Du nicht speziell erwähnt hast.

      Zusammengefasst: für Deine (unzureichende) Problembeschreibung ist dies keine hinreichende Lösung.

      a) Aus Deinem Lösungsansatz entnehme ich:

      id | bar | foo
      ---+-----+----
       1 | aaa | bb
       2 |  aa | c
       3 |   a | aaaab

      möchtest Du in der Reihenfolge

      id | bar | foo
      ---+-----+------
       3 |   a | aaaab
       1 | aaa | bb
       2 |  aa | c

      sortiert haben, weil die verketteten Inhalte so sortiert würden. Ist das richtig?

      Wenn ja, musst Du berücksichtigen,

      • dass MySQL dafür keinen Index verwenden kann (AFAIR).
      • dass Deine Lösung voraussetzt, dass die Werte der Spalte "foo" *nicht* den
          Wert NULL annehmen dürfen.

      Wenn nein? Dann gib eine bessere Problembeschreibung!

      Freundliche Grüße

      Vinzenz

      1. Hi Vinzenz und suit,

        darf ich ergänzen, dass ich das Posting so verstanden habe:

        "Nimm als ersten Sortierwert den Wert von bar, falls != null, ansonsten den Wert von foo - als zweiten dann foo. Das übersetzt sich fast wörtlich in SQL:

          
        ORDER BY ifnull(bar, foo), foo  
        
        

        Oder?

        Viele Grüße
        der Bademeister

        1. "Nimm als ersten Sortierwert den Wert von bar, falls != null, ansonsten den Wert von foo - als zweiten dann foo.

          Korrekt.

          ORDER BY ifnull(bar, foo), foo

            
          Firma dankt.  
            
          Ich musste es allerdings mit IF lösen, da das Feld NULL oder einen Leerstring enthalten kann.  
            
          `ORDER BY IF(bar = '' OR bar IS NULL, foo, bar), foo`{:.language-sql}
          
          1. Hallo,

            "Nimm als ersten Sortierwert den Wert von bar, falls != null, ansonsten den Wert von foo - als zweiten dann foo.
            Korrekt.

            ORDER BY IF(bar = '' OR bar IS NULL, foo, bar), foo

            Nur ein Hinweis: das Ergebnis ist ein ganz anderes als bei Deiner CONCAT-Idee.

            Freundliche Grüße

            Vinzenz

            1. Nur ein Hinweis: das Ergebnis ist ein ganz anderes als bei Deiner CONCAT-Idee.

              Das vermutete ich bereits, darum auch meine Befürchtung diesbezüglich in meinem Ausgangposting.

              Die CONCAT-Idee waren eben nicht das, was ich wollen :) mitunter ein grund für meine Frage.

              Danke nochmal für die raschen Antworten an euch beide.

      2. sortiert haben, weil die verketteten Inhalte so sortiert würden. Ist das richtig?

        Ja.

        Wenn ja, musst Du berücksichtigen,

        • dass MySQL dafür keinen Index verwenden kann (AFAIR).

        Das wäre kein Problem, da der Umfang der Datensätze gering ist - ein paar tausend. Und das ganze dann letztendlich gecacht wird - die 40 ms pro Tag gönne ich mir :)

        • dass Deine Lösung voraussetzt, dass die Werte der Spalte "foo" *nicht* »»   Wert NULL annehmen dürfen.

        Das ist richtig - CONCAT('sample', NULL) - ergibt NULL.