Paco: SELECT/JOIN/SQL-statement richtig formulieren

Hallo!
Ich habe Schwierigkeiten eine SQL-Abfrage zu formulieren, die die Ausgabe erziehlt, die ich brauche. Ich bastele an einem Projektmanagement-Tool (Apache und mySQL-Datenbank) das Projekte, Benutzer und Aufgaben beinhaltet. mein Datenbankdesign sieht (dank EKKis Hilfe) mittlerweile folgendermaßen aus:

tabelle projekte
ID | projekt| ...
---+--------+-----
 1 | blabla |
 2 | blubb  |

users
UserID | UserName | ...
-------+----------+-----
 1     | Hans     |
 2     | Jochen   |
 3     | Peter    |

rolle
ID | name          | ...
---+---------------+-----
 1 | Projektleiter |
 2 | Technik       |
 3 | Grafik        |

dispo
ID | projekt_id | user_id | rolle_id | ...
---+------------+-------------+----------+-----
 1 |          1 |           1 |        1 |
 2 |          1 |           3 |        2 |
 3 |          1 |           4 |        3 |
 4 |          2 |           2 |        1 |
 5 |          2 |           1 |        2 |
 6 |          2 |           3 |        3 |

Meine Abfrage bisher:

SELECT projekt, rolle, GROUP_CONCAT(DISTINCT UserName)
        FROM projekte
        LEFT JOIN dispo
  ON projekte.id = dispo.projekt_id
        LEFT JOIN users
  ON dispo.user_id = users.UserID
 JOIN rollen
  ON dispo.rolle_id = rollen.id
        GROUP BY projekt

funktioniert und liefert mir z.B.:

projekt | rolle          | GROUP_CONCAT(DISTINCT UserName)
--------+----------------+--------------------------------
blabla  | projektleiter  | Hans
blubb   | Technik        | Hans, Jochen
blerch  | grafik         | Jochen, Peter

Was ich haben möchte, ist eine Ausgabe wie folgende:

projekt | projektleiter  | technik | grafik
--------+----------------+---------+--------
blabla  | Hans           | Hans    |
        |                |         |Hans
        |                |         |Jochen
blerch  | Jochen         | Jochen  |Peter
        |                | Hans    |

Also die Werte der Rollen als Spaltenüberschriften. Das bekomme ich aber nicht hin. Wie muß ich denn JOINen um "SELECT projekt, projektleiter, technik..." ausführen zu können?

Vielen Dank,
Paco

  1. moin,

    SELECT projekt, rolle, GROUP_CONCAT(DISTINCT UserName)
            FROM projekte
            LEFT JOIN dispo
      ON projekte.id = dispo.projekt_id
            LEFT JOIN users
      ON dispo.user_id = users.UserID
    JOIN rollen
      ON dispo.rolle_id = rollen.id
            GROUP BY projekt

    funktioniert und liefert mir z.B.:

    jeder hat ja seinen stil, wie man abschreiben erstellt, aber bei diese darstellung ist schon nicht einfach zu lesen. nur als tipp gemeint, versuche mal eine andere darstellung, auch aliasnamen helfen immens.

    nun aber zu der eigentlichen frage, diese abfrage kann so nicht funktionieren, du unterliegst einem mysql bug. dafür gibt es mittlerweile soviel postings hier im forum über diesen "bug", dass wir mysql eine rechnung stellen sollten. du gibst die spalten "rolle" aus, ohne darüber gruppiert zu haben.

    das andere ist, du machst auf die tabelle "dispo", die du vorher mit einem OUTER LEFT JOIN eingebunden hast, zusätzlich danach noch einen INNER JOIN auf eine die tabelle "rollen". das macht keinen sinn, weill du dann wieder datensätze verlieren kannst, die du durch den LEFT JOIN eigentlich haben wolltest.

    und um dein problem zu lösen, dass du Datensätze als spalten darstellen willst, das geht, wenn du die Anzahl der Spalten genau weisst, sprich eine spalte für technik, eine für grafik .... also bekannt und endlich sind. dazu kannst du korrelierte unterabfragen benutzen. unterabfragen bei mysql gehen aber erst ab version 4.1. und da du uns version verschwiegen hast....

    Ilja

    1. jeder hat ja seinen stil, wie man abschreiben erstellt, aber bei diese darstellung ist schon nicht einfach zu lesen. nur als tipp gemeint, versuche mal eine andere darstellung, auch aliasnamen helfen immens.

      Ups, da is die Formatierung beim copy-pasten flöten gegangen, sorry.

      nun aber zu der eigentlichen frage, diese abfrage kann so nicht funktionieren, du unterliegst einem mysql bug. dafür gibt es mittlerweile soviel postings hier im forum über diesen "bug", dass wir mysql eine rechnung stellen sollten. du gibst die spalten "rolle" aus, ohne darüber gruppiert zu haben.

      Was ist denn nun genau der Bug? Die Abfrage funktioniert doch. Und was meinst du mit ausgeben ohne vorher zu gruppieren?

      das andere ist, du machst auf die tabelle "dispo", die du vorher mit einem OUTER LEFT JOIN eingebunden hast, zusätzlich danach noch einen INNER JOIN auf eine die tabelle "rollen". das macht keinen sinn, weill du dann wieder datensätze verlieren kannst, die du durch den LEFT JOIN eigentlich haben wolltest.

      Ich dachte mir das so: tabelle projekte>=tabelle dispo>=users=rolle. Also benutzer/rolle als "kleinster gemeinsamer Nenner", bzw als Teilmenge von dispo, dispo als teilmenge von projekte. Welche datensätze verliere ich denn da?

      und um dein problem zu lösen, dass du Datensätze als spalten darstellen willst, das geht, wenn du die Anzahl der Spalten genau weisst, sprich eine spalte für technik, eine für grafik .... also bekannt und endlich sind. dazu kannst du korrelierte unterabfragen benutzen. unterabfragen bei mysql gehen aber erst ab version 4.1. und da du uns version verschwiegen hast....

      Meine Serverversion ist 5.0. Also dann werde ich mich mal mit den korrelierten unterabfragen auseinandersetzen...

      Vielen Dank schonmal

      1. yo,

        Was ist denn nun genau der Bug? Die Abfrage funktioniert doch. Und was meinst du mit ausgeben ohne vorher zu gruppieren?

        eben, alle anderen dbms ausser mysql würde dir bei dieser abfrage eine fehlermeldung ausgeben und zwar zurecht. die regel besagt, du darfst nur spalten innerhalb einer gruppierung ausgeben, über die auch gruppiert wurde oder aber bestandteil einer aggregat-funktion sind. wenn dir die problematik nicht bewußt ist, suche hier einfach im forum danach.

        Ich dachte mir das so: tabelle projekte>=tabelle dispo>=users=rolle. Also benutzer/rolle als "kleinster gemeinsamer Nenner", bzw als Teilmenge von dispo, dispo als teilmenge von projekte. Welche datensätze verliere ich denn da?

        hast du den erfahrungen mit LEFT JOINS, bzw. weißt du wofür sie verwendet werden ? wenn dem so ist, sollte dir auch klar ein, dass ein OUTER JOIN (LEFT JOIN) NULL werte zurück gibt, wenn es keine passenden Datensatz auf der anderen tabellenseite findet, in deinem falle wäre es die tabelle dispo. somit hätte auch die spalte dispo.rolle_id einen NULL wert und dann werden die datensätze über den INNER JOIN mit der "rolle" tabelle wieder wegfallen. mit anderen worten, dein OUTER JOIN an der stelle ist sinnlos.

        Ilja