suit: MySQL 5.1: manuelle Sortierung bei SELECT / IN

Hallo,

kann ich die Sortierreihenfolge in einem SELECT manuell in einer Liste vorgeben?

SELECT foo FROM bar WHERE id IN(1,3,2,4)

Ausgabe (willkürlich)

id
--
1
2
3
4

Gewünschte Ausgabe

id
--
1
3
2
4

Mit anderen Worten, die Sortierreihenfolge aufgrund der Reihenfolge der Angegebenen Werte im IN-Operator?

  1. Hi!

    kann ich die Sortierreihenfolge in einem SELECT manuell in einer Liste vorgeben?

    Ja. Es gibt Fallunterscheidungsfunktionen (IF() und CASE), mit denen du entweder eine berechnete Spalte in die Ergebnismenge bringen und nach der du sortieren lassen kannst. Du kannst das auch in der ORDER-BY-Klausel notieren.

    Mit anderen Worten, die Sortierreihenfolge aufgrund der Reihenfolge der Angegebenen Werte im IN-Operator?

    Nein, die Werte in IN() interessieren beim Sortieren nicht mehr. Vermutlich hat die der Optimizer schon sortiert, um deine Anfrage effizient beantworten zu können.

    Lo!

    1. Ja. Es gibt Fallunterscheidungsfunktionen (IF() und CASE), mit denen du entweder eine berechnete Spalte in die Ergebnismenge bringen und nach der du sortieren lassen kannst. Du kannst das auch in der ORDER-BY-Klausel notieren.

      Hilft mir das in diesem Kontext weiter - sprich kann ich nach 1,3,2,4 sortieren, ohne eine wirklich vorhandene Spalte in einer Tabelle zu haben?

      Die Alternative die mir spontan eingefallen wäre ist schlichtweg Union zu verwenden und anstatt mit IN mit = zu arbeiten.

      Die manuelle Auswahl und Reihung der Datensätze in meinem Fall übersteigt niemals 5 und wird im Regelfall 2 belaufen - die werden "relativ selten" abgefragt, dann gecacht und die fertigen Dokumente werden über ein CDN verteilt - Performance ist her also weniger das Problem.

      1. Hi!

        Ja. Es gibt Fallunterscheidungsfunktionen (IF() und CASE), mit denen du entweder eine berechnete Spalte in die Ergebnismenge bringen und nach der du sortieren lassen kannst. Du kannst das auch in der ORDER-BY-Klausel notieren.

        Hilft mir das in diesem Kontext weiter - sprich kann ich nach 1,3,2,4 sortieren, ohne eine wirklich vorhandene Spalte in einer Tabelle zu haben?

        Ich sagte "berechnete Spalte", sowas wie: SELECT foo, foo + 2 FROM ...

        Da das DBMS ja anhand der Selektionskriterien eine eindeutige Auswahl treffen kann, kannst du auch diese Selektionskriterien so in das CASE-Konstrukt einbauen, dass eindeutig sortierbare Werte den jeweiligen Datensätzen zugeordnet werden können. (IF() hab ich grad nicht mehr erwähnt, weil ein CASE vielleicht mehr Schreibaufwand bedeutet, aber verschachtelte IF() schlechter wartbar sind.)

        Die Alternative die mir spontan eingefallen wäre ist schlichtweg Union zu verwenden und anstatt mit IN mit = zu arbeiten.
        Die manuelle Auswahl und Reihung der Datensätze in meinem Fall übersteigt niemals 5 und wird im Regelfall 2 belaufen

        Wie auch immer, du wirst ein Stück Code brauchen, das dir die Abfrage passend zusammenbaut. Das muss sowohl die unterschiedlichen Anzahl der IN()-Werte berücksichtigen, als auch das daraus resultierende unterschiedlich lange CASE-Konstrukt, oder aber alternativ die UNION-Abfragen.

        UNION würde ich nicht nehmen, zuviele Wiederholungen. Die werden zwar sichererlich automatisch erzeugt was keine Copy&Paste-Probleme bereiten wird, aber schön ist was anderes.

        Lo!

        1. Ich sagte "berechnete Spalte", sowas wie: SELECT foo, foo + 2 FROM ...

          Hab ich überlesen, jetzt ist mir alles klar - stand auf der Leitung.

          UNION würde ich nicht nehmen, zuviele Wiederholungen. Die werden zwar sichererlich automatisch erzeugt was keine Copy&Paste-Probleme bereiten wird, aber schön ist was anderes.

          Da gebe ich dir recht.

          Vielen dank für die schnelle Hilfe.

  2. http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_find-in-set
    ORDER BY FIND_IN_SET(id, '1,3,2,4')

    1. Hi!

      http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_find-in-set
      ORDER BY FIND_IN_SET(id, '1,3,2,4')

      Das muss ich mir irgendwann mal merken, dass es das gibt ...

      Lo!

      1. Das muss ich mir irgendwann mal merken, dass es das gibt ...

        Eventuell wäre es auch nicht verkehrt, das mal in Doku zu erwähnen - weder bei ORDER BY noch bei FIND_IN_SET() ist diese Kombinationsmöglichkeit angeführt.

    2. http://dev.mysql.com/doc/refman/5.1/en/string-functions.html#function_find-in-set
      ORDER BY FIND_IN_SET(id, '1,3,2,4')

      Funktioniert perfekt - wusste garnicht, dass man FIND_IN_SET() dafür "missbrauchen" kann.

      Jetzt war ich grade dabei dedlfix' Lösungsvorschlag anzugehen, da lieferst du gleich eine noch bessere Lösung.