Guma: MySQL -> relationale Datenbank ausgeben mit INNER JOIN

Hallo zusammen,
ich stecke gerade fest und komme nicht weiter...

Entwicklungsumgebung MySQL & PHP

Ich habe drei Tabellen:

Tabelle 1 (logo_firma):
li_id  |  li_name

Tabelle 2 (logo_form):
id  | id_firma  |  hotelbeschreibung

Tabelle 3 (logo_leistungen):
id_firma  | leistung

Die sind so gefüllt:

Tabelle 1 (logo_firma):
| 17  |  Hotel Krone   |
| 18  |  Hotel am See  |

Tabelle 2 (logo_form):
| 1  | 17 |  Gasthof m. Pool  |
| 2  | 18 |  Direkt am See    |

Tabelle 3 (logo_leistungen):
| 17  | sauna          |
| 17  | pool           |
| 17  | whirlpool      |
| 18  | sauna          |
| 18  | bootsausflüge  |
| 18  | fitnessraum    |

Jetzt will ich mit Join und Select alle ausgeben:
17 (id_firma) | Hotel Krone (li_name) | Gasthof m. Pool (hotelbeschreibung) | sauna, pool, whirlpool (leistung)
18 (id_firma) | Hotel am See (li_name) | Direkt am See (hotelbeschreibung) | sauna, bootsausflüge, fitnessraum (leistung)

Dazu habe ich folgendes ausprobiert:

SELECT
    t1.id_firma,
    li_name,
    leistung,
    id,
    hotelbeschreibung
FROM (logo_form AS t1
INNER JOIN logo_leistungen AS t2
ON t1.id_firma = t2.id_firma)
INNER JOIN logo_firma
ON t1.id_firma = logo_firma.li_id

SQL liefert mir dann folgendes:

17 | Hotel Krone | sauna | Gasthof m. Pool|
17 | Hotel Krone | pool | Gasthof m. Pool|
17 | Hotel Krone | whirlpool | Gasthof m. Pool|
18 | Hotel am See | sauna | Gasthof m. Pool|
18 | Hotel am See | bootsausflüge | Gasthof m. Pool|
18 | Hotel am See | fittnessraum | Gasthof m. Pool|

Frage:
Ich möchte nicht für jede Leistung das Hotel entsprechend ausgeben sondern das hotel auf der Webseite mit allen Leistungen anzeigen:
17 | Hotel Krone | sauna, pool, whirlpool | Gasthof m. Pool|
18 | Hotel am See | sauna,bootsausflüge,fittnessraum  | Gasthof m. Pool|

Wie gehe ich da vor?

Grüße von Guma

  1. Hallo guma,

    SQL liefert mir dann folgendes:

    17 | Hotel Krone | sauna | Gasthof m. Pool|
    17 | Hotel Krone | pool | Gasthof m. Pool|
    17 | Hotel Krone | whirlpool | Gasthof m. Pool|
    18 | Hotel am See | sauna | Gasthof m. Pool|
    18 | Hotel am See | bootsausflüge | Gasthof m. Pool|
    18 | Hotel am See | fittnessraum | Gasthof m. Pool|

    Frage:
    Ich möchte nicht für jede Leistung das Hotel entsprechend ausgeben sondern das hotel auf der Webseite mit allen Leistungen anzeigen:
    17 | Hotel Krone | sauna, pool, whirlpool | Gasthof m. Pool|
    18 | Hotel am See | sauna,bootsausflüge,fittnessraum  | Gasthof m. Pool|

    Wie gehe ich da vor?

    Wenn Deine MySQL-Version mindestens 4.1 ist, dann kannst Du GROUP_CONCAT nutzen.

    Bitte sei so nett, und gib' bei Fragen zu MySQL stets die verwendete Version an, weil sich die Leistungsfähigkeit und Funktionalität von MySQL von Version zu Version sehr stark unterscheidet. Und nimm bitte nicht an, dass wir uns von einem Thread zum nächsten die Version merken können :-)

    Freundliche Grüße

    Vinzenz

    1. Danke für die Antwort,

      meine MySQL-Version ist 5.0

      Mit dem habe ich es versucht:
      SELECT
          t1.id_firma,
          li_name,
          leistung,
          id,
          hotelbeschreibung
      FROM (logo_form AS t1
      INNER JOIN logo_leistungen AS t2
      ON t1.id_firma = t2.id_firma)
      INNER JOIN logo_firma
      ON t1.id_firma = logo_firma.li_id
      GROUP_CONCAT(leistung)
      FROM logo_leistungen

      ich bekomme da immer eine Fehlermeldung:
      #1064 - You have an error in your SQL syntax;

      was mache ich verkehrt?
      Guma

      1. Moin!

        ich bekomme da immer eine Fehlermeldung:
        #1064 - You have an error in your SQL syntax;

        was mache ich verkehrt?

        Die PLatzierung von GROUP_CONCAT. Das ist eine Aggregatfunktion wie MAX, SUM oder COUNT.

        Hättest du im Handbuch aber auch nachlesen können.

        - Sven Rautenberg

        --
        "Love your nation - respect the others."
      2. Hallo

        meine MySQL-Version ist 5.0

        prima. Also geht es. Du solltest beachten, dass es sich bei GROUP_CONCAT um eine Aggregatsfunktion handelt, die zusammen mit GROUP BY eingesetzt wird.

        Also in etwa so, ich habe Dein Statement sonst nicht geprüft:

          
        
        > SELECT  
        >     t1.id_firma,  
        >     li_name,  
        >     hotelbeschreibung,  
        >     GROUP_CONCAT(leistung) AS Leistungen -- Spaltenalias zum besseren Zugriff  
        
                                                   -- mit Einsatz von GROUP_CONCAT  
        
        > FROM (logo_form AS t1  
        > INNER JOIN logo_leistungen AS t2  
        > ON t1.id_firma = t2.id_firma)  
        > INNER JOIN logo_firma  
        > ON t1.id_firma = logo_firma.li_id  
        
          GROUP BY                                 -- hier sind laut SQL-Standard alle Spalten  
              t1.id_firma,                         -- aufzuführen, auf die keine Aggregatsfunktion  
              li_name,                             -- angewendet wird [1]  
              hotelbeschreibung
        

        Freundliche Grüße

        Vinzenz

        [1] Ja ich weiß, dass MySQL das laxer handhabt.
            Ich mache das lieber ordentlich.

        1. Danke vinc! genau so sieht die ausgabe prima aus, es klappt auf anhieb dank sql 5

          Guma

        2. Noch eine Frage dazu Vinzenz,

          ich habe versucht eine kategorie tabelle noch abfragen zu lassen. Wenn jetzt ein hotel nicht mindestens eine Kategorie gewählt hat wird es erst gar nicht aufgeführt. kann man das ändern?

          Hier meine SQl-Abfrage:

          SELECT
             t1.id_firma,
             li_name,
             hotelbeschreibung,
             GROUP_CONCAT(leistung) AS Leistungen,
             GROUP_CONCAT(kategorie) AS Kategorien

          FROM (logo_form AS t1
           INNER JOIN logo_leistungen AS t2
           ON t1.id_firma = t2.id_firma)
          INNER JOIN logo_firma
           ON t1.id_firma = logo_firma.li_id
          INNER JOIN logo_kategorien AS t3
           ON t1.id_firma = t3.id_firma

          GROUP BY
                t1.id_firma,
                li_name,
                hotelbeschreibung

          Guma

          1. Hallo guma,

            ich habe versucht eine kategorie tabelle noch abfragen zu lassen. Wenn jetzt ein hotel nicht mindestens eine Kategorie gewählt hat wird es erst gar nicht aufgeführt. kann man das ändern?

            ja klar kann man das ändern. Deswegen hat Rouven doch den Artikel Einführung: JOINs geschrieben - ja genau einer der Artikel, die Dir gestern wahsaga ans Herz gelegt hat, und geht dort auf den LEFT JOIN ein.

            Freundliche Grüße

            Vinzenz

  2. yo,

    Entwicklungsumgebung MySQL & PHP

    welche versionen ?

    Tabelle 1 (logo_firma):
    li_id  |  li_name

    Tabelle 2 (logo_form):
    id  | id_firma  |  hotelbeschreibung

    welche beziehung besteht zwischen diesen beiden tabellen etwa eine 1:1 beziehung ?

    Ich möchte nicht für jede Leistung das Hotel entsprechend ausgeben sondern das hotel auf der Webseite mit allen Leistungen anzeigen:
    17 | Hotel Krone | sauna, pool, whirlpool | Gasthof m. Pool|
    18 | Hotel am See | sauna,bootsausflüge,fittnessraum  | Gasthof m. Pool|

    Wie gehe ich da vor?

    ja, dafür bietet speziell mysql eine besondere aggregat-funktion an, nämlich GROUP_CONCAT [Link:http://dev.mysql.com/doc/refman/4.1/en/group-by-functions.html]

    Ilja

  3. Hi Guma,

    DAS typische Problem: Eine Spaltenansicht als Zeilenansicht darstellen.

    Ich fürchte, da hilft nur folgendes:

    1.) Alle Leistungen eines Hotels aus der Bank (MySQL) in ein Array (PHP)kopieren. Am Ende hast Du dann einen String Hotel, einen String "Gasthof mit Pool" und ein Array mit den ganzen leistungen.

    2.) Sobald sich der Hotelname ändert, die beiden Strings und das Array ausgeben und wie bei 1 verfahren

    3.) Sobald Ende der Datenmenge des Select-Statements, wie bei 2.) verfahren, da Du ja noch die ganze Info für das letzte Hotel im Speicher hast.

    Gruß

    Hans

    1. yo,

      Ich fürchte, da hilft nur folgendes:

      hast du dir mal den lösungsansatz von Vinz und mir angeschaut, bzw. falls vorhanden was von unterabfragen gehört ?

      Ilja

      1. Wie sieht hier eine Unterabfrage denn aus? ein weiteres Select?

        Guma

        1. yo,

          Wie sieht hier eine Unterabfrage denn aus? ein weiteres Select?

          ja, es wäre eine weitere SELECT innheralb der Ausgabespalten des oberen SELECT's, oder besser gesagt eine korellierende unterabfrage.

          Ilja

      2. Hi !

        hast du dir mal den lösungsansatz von Vinz und mir angeschaut, bzw. falls vorhanden was von unterabfragen gehört ?

        Unterabfragen? Ne, Du ich kenne nur subselects. Was sind denn Unterabfragen?

        Gruß

        Hans

        1. yo,

          Unterabfragen? Ne, Du ich kenne nur subselects. Was sind denn Unterabfragen?

          ist das eine ernsthafte frage ?

          Ilja

          1. Hi !

            ist das eine ernsthafte frage ?

            Die Gleiche hätte ich vorher auch stellen können ;-)

            Gruß

            Hans

            1. yo,

              Die Gleiche hätte ich vorher auch stellen können ;-)

              sicherlich kannst du das, aber hast du dir schon mal die lösungen angeschaut ? daraus ergibt sich nämlich, dass es unnötig ist, das problem in php anzugehen.

              Ilja

    2. Geht das nicht einfacher Hans?
      Ich will nur nicht jede leistung einzeln als zeile ausgegeben bekommen, sondern zusammen ausgeben.
      Guma

      1. Hallo.

        Geht das nicht einfacher Hans?

        Meintest du "Geht das nicht, einfacher Hans?" oder "Geht das, nicht einfacher Hans?"?
        MfG, at