Vinzenz Mai: MYSQL-Abfrage mit Unterarray

Beitrag lesen

Hallo huby,

Die Tabelle "personen" sieht so aus:

UserID  name  ort
1       Hans    München
2       Claudia Berlin
3       Beate   Düsseldorf
4       Toni    Innsbruck

Die Tabelle "hobby" sieht so aus:

ID    name
1     Schifahren
2     Segeln
3     schwimmen
4     joggen
5     klettern
6     wandern

Die Tabelle "pers_hobby" sieht so aus:

UserID  ID
1       1
1       4
2       1
3       4
3       5
3       6
4       2
4       3
4       5

Mit folgender Abfrage ->

  

> SELECT p.UserID NR, p.name Name, p.ort Ort, h.name Hobby  
> FROM personen p, hobby h, pers_hobby ph  
> WHERE p.UserID = ph.UserID  
> AND ph.ID = h.ID;  

bekomme ich dieses Ergebnis:

NR  Name      Ort          Hobby
1   Hans      München      Schifahren
1   Hans      München      joggen
2   Claudia   Berlin       Schifahren
3   Beate     Düsseldorf   joggen
3   Beate     Düsseldorf   klettern
3   Beate     Düsseldorf   wandern
4   Toni      Innsbruck    Segeln
4   Toni      Innsbruck    schwimmen
4   Toni      Innsbruck    klettern

Ich bräuchte aber ein solches Ergebnis:

NR  Name      Ort          Hobby
1   Hans      München      Schifahren
                           joggen
2   Claudia   Berlin       Schifahren
3   Beate     Düsseldorf   joggen
                           klettern
                           wandern
4   Toni      Innsbruck    Segeln
                           schwimmen
                           klettern

Hobby sollte ein Unterarray der Abfrage sein!

Zu allererst solltest Du Dir darüber klar werden, dass das Ergebnis einer Abfrage eine Tabelle ist. Das hat nichts mit einem Array zu tun. Viele Programmiersprachen nutzen eine Schnittstelle, die ihnen einzelne Datensätze als Array zurückliefert.

In Deinem einfachen Fall kannst Du fast das gewünschte bekommen, denn außer den verschiedenen Einträgen in der Spalte Hobby hängt alles direkt vom Primärschlüssel Deiner Personentabelle ab. Zusätzlich kennt MySQL ab Version 4.1 die Aggregatsfunktion GROUP_CONCAT(), die Dir weiterhelfen kann.

Ich persönlich rate Dir weiter dazu, die explizite Join-Syntax zu verwenden, siehe dazu Rouven Thimms Einführung in Joins.

  
SELECT  
    p.UserID NR,  
    p.name Name,  
    p.ort Ort,  
    GROUP_CONCAT(h.name SEPARATOR ';') Hobby  
FROM  
    personen p,  
INNER JOIN                -- explizite Join-Syntax  
    pers_hobby ph         -- halte ich für übersichtlicher  
ON  
    p.UserID = ph.UserID  
INNER JOIN  
    hobby h  
ON  
    ph.ID = h.ID  
GROUP BY      -- Bei Verwendung einer Aggregatsfunktion musst Du nach allen  
              -- Spalten gruppieren, auf die _keine_ Aggregatsfunktion angewandt  
              -- wird [1].  
    p.UserID,  
    p.name,  
    p.ort

liefert Dir:

NR  Name      Ort          Hobby
1   Hans      München      Schifahren;joggen
2   Claudia   Berlin       Schifahren
3   Beate     Düsseldorf   joggen;klettern;wandern
4   Toni      Innsbruck    Segeln;schwimmen;klettern

Die API (d.h. der Programmiersprache, mit der Du auf die Datenbank zugreifst) stellt Dir sicher bequeme Funktionen zur Verfügung um die Zeichenketten der Spalte Hobby am gewählten Trennzeichen (Du kannst gerne auch etwas anderes als das Semikolon verwenden) in ein Array zu splitten (oder explodieren zu lassen).

Freundliche Grüße

Vinzenz

[1] Auch wenn MySQL das standardmäßig zulässt.