# Join über 3 Tabellen



## rogo (23. Juni 2004)

Hallo zusammen,

ich schreibe gerade an einer Zeiterfassung und habe dabei folgende Tabellen
Die Tabelle Zeiten besitzt *entweder*  eine funktionsid *oder* eine dienstleistungsid

Tabelle 1 : Zeiten
Zeiten_ID
datum
stunden
Funktionsid (Fremdschlüssel aus Funktionen)
Dienstleistungsid (Fremdschlüssel aus Dienstleistungen)
...

Tabelle 2 : Funktionen
funktionsid
funktionsname
...

Tabelle 3 : Dienstleistungen
dienstleistungsid
dienstleistungsname
...


Meine Abfrage sollte folgendes Ergebnis liefern.
Eine Spalte enthält den funktions. bzw. dienstleistungsnamen, die andere Spalte sollte mit einem Nullwert aufgefüllt werden

datum    /     stunden      /      funktionsname     / dienstleistungsname


Ich habe mir bisher folgende Abfrage überlegt

SELECT z.datum, z.stunden, f.funktionsname, d.dienstleistungsname
FROM zeiten z, funktionen f, dienstleistungen d
WHERE z.funktionsid = f.funktionsid or z.dienstleistungsid = d.dienstleistungsid

Leider schreibt die Abfrage keine Nullwerte in die Spalte.

Hat jemand eine Lösung für mein Problem.

Danke Mirco


P.s.

zum besseren Verständnis ein kleines Beispiel.


----------



## rogo (23. Juni 2004)

Zeiten
ID     Tag                  Stunden     Funktionsid     Dienstleistungsid
z1     01.01.2004           2                     f1              
z2     02.01.2004           3                     f2
z3     03.01.2004           4                                                    d1

Funktionen
Funktionsid                        Funktionsname
       f1                                      Funktion1
       f2                                      Funktion 2

Dienstleistungen
Dienstleistungsid             Dienstleistungsname
       d1                                      Dienstleistung1
       d2                                      Dienstleistung2


Gewünschtes Ergebnis:
Tag                 Stunden            Funktionsname       Dienstleistungsname
01.01.2004         2                        Funktion1
02.01.2004         3                        Funktion2
03.01.2004         4                                                              Dienstleistung1


Tatsächliches Ergebnis
Tag                 Stunden            Funktionsname       Dienstleistungsname
01.01.2004          2                         Funktion1                   Dienstleistung1
01.01.2004          2                         Funktion1                   Dienstleistung2
02.01.2004          3                         Funktion2                   Dienstleistung1
02.01.2004          3                         Funktion2                   Dienstleistung2
03.01.2004          4                         Funktion1                   Dienstleistung1
03.01.2004          4                         Funktion2                   Dienstleistung1


Hoffe es verdeutlicht das Problem.


Danke

Mirco


----------



## Gorcky (23. Juni 2004)

Mit der verkürzten JOIN-Anweisung kannst du - soweit ich weiß - nur INNER Joins vernünftig abdecken. 
Ich würde es daher so schreiben:
	
	
	



```
SELECT z.datum, z.stunden, f.funktionsname, d.dienstleistungsname
FROM zeiten z LEFT OUTER JOIN funktionen f ON z.funktionsid = f.funktionsid LEFT OUTER JOIN dienstleistungen d ON z.dienstleistungsid = d.dienstleistungsid
```
Was sagt er dazu?


----------



## rogo (24. Juni 2004)

Hallo Gorky !

Erst einmal danke für deine Antwort.

Da ich auch schon einmal die gleiche Lösungsidee wie du hatte, er mir damals aber immer einen Syntaxfehler ausgab, habe ich es nochmals probiert. (Zwei denken meistens richtig ).

Mit zwei einfachen Klammern hat es dann funktioniert

SELECT z.datum, z.stunden, f.funktionsname, d.dienstleistungsname 
FROM   *(*   zeiten z LEFT OUTER JOIN funktionen f ON z.funktionsid = f.funktionsid   *)*   LEFT OUTER JOIN dienstleistungen d ON z.dienstleistungsid = d.dienstleistungsid


Danke

Mirco


----------



## TTime (25. Juni 2004)

hier probier das mal:

SELECT z.datum, z.stunden, f.funktionsname, 'null'
d.dienstleistungsname 
FROM  zeiten z funktionen f 
where z.funktionsid = f.funktionsid 
union
SELECT z.datum, z.stunden, 'null', d.dienstleistungsname 
FROM  zeiten z, dienstleistungen d 
where z.dienstleistungsid = d.dienstleistungsid

das Ergebnis sollte deiner Vorstellung ziemlich nahe kommen ^^


----------



## muipo (3. März 2009)

Hallöchen zusammen 

Das Thema hier ist zwar schon dezent eingestaubt, aber dennoch stehe ich als Anfänger genau vor solch einer Problematik und finde keine Lösung und auch keinen Ansatz im Internet der mir weiterhelfen könnte...

folgende Voraussetzungen:

Tabelle1: Veranstaltungen
id   datum   titel

Tabelle2: angemeldete Besucher
id   besucherid

Tabelle3: registrierte User
userid   email


Nun das Problem:
Ich benötige eine strukturierte Ausgabe zur jeweiligen Veranstaltung, mit den Emailadressen der angemeldeten Besucher um sie anzuschreiben

Datum1 Titel1     
Email1
Email4 
Email9 
Email16

Datum2 Titel2
Email3
Email4
Email7
Email16
Email29     ...usw

also für jede Veranstaltungsid Datum und Titel ausgeben, dann die jeweiligen besucherids mit den userid's vergleichen, um entsprechende emailadressen zu ermitteln und ebenfalls auszugeben..

Hoffe man konnte es nachvollziehen und dass irgendwer so freundlich ist mir weiterzuhelfen, vielen lieben dank im vorraus!


----------



## kuddeldaddeldu (3. März 2009)

Hi,

ganz grob würde ich sagen, Du brauchst 2 INNER JOINS:

veranstaltungen INNER JOIN besucher INNER JOIN user

Das ganze sortierst Du dann nach Datum und Titel und machst in Deinem verarbeitenden Script einen Gruppenwechsel.

Feddich... 

LG


----------



## muipo (4. März 2009)

Vielen Dank für so schnelle Reaktion hätte ich ja nun garnicht erwarten, top 
Die logische Abfolge hab ich "oh wunder" dann auch mal begriffen, aber ich erhalte keine Ausgabe... Ich hoffe dass hier niemand die Hände überm Kopf zusammen schlagen muss aber das was ich mir zusammengeschustert habe sieht wie folgt aus...


```
<?php
  if (!mysql_connect($dbhost, $dbuser, $dbpass)) {
    die ("Verbindung zum Server fehlgeschlagen.");
  }
  if (!mysql_select_db($database)) {
    die ("Datenbank nicht gefunden.");
  }

$read_cursor = mysql_query("SELECT datum, titel, email FROM veranstaltungen INNER JOIN ON veranstaltungen.id = anmeldungen.eventid INNER JOIN ON anmeldungen.uid = user.id");

  while($result = mysql_fetch_array($read_cursor)) {
    echo $result[datum]." ". $result[titel]." ". $result[email] "<br>\n";
  }

  mysql_close();
?>
```

Achja, Sortierung und so hab ich noch nicht dran gearbeitet, primär möchte ich erstmal die Auflistung haben...


----------



## kuddeldaddeldu (4. März 2009)

Hi,

ein " or die(mysql_error());" hinter mysql_query() hätte Dir gezeigt, dass die Abfrage fehlschlägt. 
Du solltest in der Abfrage auch mal angeben, _welche_ Tabellen Du joinen willst...


```
SELECT felder FROM tabelle1 INNER JOIN tabelle2 ON ...
```

LG


----------



## muipo (4. März 2009)

mein Held *schwärm* 

Tausend Dank, es klappt so wie es soll... Sorry, aber wusel mich erst 3 Tage durch sql... da kann man auch so ne Kleinigkeit wie ne Tabellenangabe schonmal vergessen 

LG


----------

