# [MySQL] 4 Tabellen miteinander verknüpfen (JOIN)?



## preko (10. Januar 2008)

Hi,

ich möchte 4 Tabellen miteinander verknüpfen, da ich aus diesen jeweils zur Darstellung einer Seite einzelne Datensätze benötige.

Die Tabellen sind im Prinzip wie folgt aufgebaut:

tabelle_1:
ort_id | ort_name

tabelle_2:
anbieter_id | anbieter_bezeichnung | ort_id

tabelle_3:
user_id | user_name

tabelle_4:
ort_id | anbieter_id | user_id | vertrag

Ich möchte nun die Tabellen verknüpfen, so daß ich jeweils die benötigten Daten daraus "ziehen" kann.

Ich stelle mir etwas wie das folgende vor:

```
...
$id = (int) $_POST['id'];

$sql_query = "SELECT
                                 tabelle_1.ort_id AS ort_id,
                                 tabelle_1.ort_name AS ort_name,
                                 tabelle_2.anbieter_id AS anbieter_id,
                                 tabelle_2.anbieter_bezeichnung AS anbieter_bezeichnung,
                                 tabelle_2.ort_id,
                                 tabelle_3.user_id AS user_id,
                                 tabelle_3.user_name AS user_name,
                                 tabelle_4.ort_id,
                                 tabelle_4.anbieter_id,
                                 tabelle_4.user_id,
                                 tabelle_4.vertrag AS vertrag
                      FROM
                                `tabelle_4`
                      INNER JOIN
                                `tabelle_2` ON tabelle_4.anbieter_id = tabelle_2.anbieter_id
                      INNER JOIN
                                `tabelle_1` ON tabelle_4.ort_id = tabelle_1.ort_id
                      AND
                                `tabelle_3` ON tabelle_4.user_id = tabelle_3.user_id
                      WHERE
                                `status` = '1'
                      AND
                                `id` = '$id'                     
";
$result = mysql_query($sql_query);
while( $row = mysql_fetch_array($result,MQSQLASSOC) ) {

echo $row['ort_id']."<br />";
echo $row['ort_name']."<br />";
echo $row['anbieter_id']."<br />";
echo $row['anbieter_bezeichnung']."<br />";
echo $row['user_id']."<br />";
echo $row['user_name']."<br />";
echo $row['vertrag']."<br />"
}
...
```
Leider bekomme ich die Meldung:


> Warning: mysql_fetch_array(): supplied argument ist not a valid MySQL result resource in D:\nur\ein\projekt.php on line 100



Jetzt nun die Königsfrage:

wo liegt mein Fehler, oder besser gesagt, wie kann man es lösen?


Beste Grüße,
preko


----------



## CraisiePrinzZ (10. Januar 2008)

Probiers mal so und wenn das nicht geht vielleicht mal mit einem LEFT JOIN.


```
$sql_query = "SELECT
                                 tabelle_1.ort_id AS ort_id,
                                 tabelle_1.ort_name AS ort_name,
                                 tabelle_2.anbieter_id AS anbieter_id,
                                 tabelle_2.anbieter_bezeichnung AS anbieter_bezeichnung,
                                 tabelle_2.ort_id,
                                 tabelle_3.user_id AS user_id,
                                 tabelle_3.user_name AS user_name,
                                 tabelle_4.ort_id,
                                 tabelle_4.anbieter_id,
                                 tabelle_4.user_id,
                                 tabelle_4.vertrag AS vertrag
                      FROM ((
                                `tabelle_4`
                      INNER JOIN
                                `tabelle_2` ON tabelle_4.anbieter_id = tabelle_2.anbieter_id )
                      INNER JOIN
                                `tabelle_1` ON tabelle_4.ort_id = tabelle_1.ort_id )
                      INNER JOIN
                                `tabelle_3` ON tabelle_4.user_id = tabelle_3.user_id 
                      WHERE
                                `status` = '1'
                      AND
                                `id` = '$id'                     
";
```

Und vielleicht solltest du die einzelnen Felder nicht gleich benennen.


----------



## aGeNET (10. Januar 2008)

Hallo,
wenn ich richtig liege vergleichst du eine Spalte *id* mit der übergebenen Variable *$id*:

```
AND `id` = '$id'
```
Problem hierbei ist, dass diese Spalte nirgends in der eigentlichen Abfrage auftaucht.
Es müsste beispielsweise so aussehen:

```
AND `ort_id` = '$id'
```
In der WHERE Clausel fragst du nach *status*, aber in welcher Tabelle steht der Status?

Die Folge daraus ist, dass es immer kein Ergebnis gibt bzw. zu einer Fehlermeldung kommt.


----------



## preko (10. Januar 2008)

@aGeNET:

vielen Dank für die schnelle Antwort. Sorry, in der Eile sind mir die Sachen durchgegangen. 

Es müsste wie folgt lauten:

```
... 
$id = (int) $_POST['id']; 

$sql_query = "SELECT 
                                 tabelle_1.ort_id AS ort_id, 
                                 tabelle_1.ort_name AS ort_name, 
                                 tabelle_1.status AS status,
                                 tabelle_2.anbieter_id AS anbieter_id, 
                                 tabelle_2.anbieter_bezeichnung AS anbieter_bezeichnung, 
                                 tabelle_2.ort_id, 
                                 tabelle_3.user_id AS user_id, 
                                 tabelle_3.user_name AS user_name, 
                                 tabelle_4.ort_id, 
                                 tabelle_4.anbieter_id, 
                                 tabelle_4.user_id, 
                                 tabelle_4.vertrag AS vertrag 
                      FROM 
                                `tabelle_4` 
                      INNER JOIN 
                                `tabelle_2` ON tabelle_4.anbieter_id = tabelle_2.anbieter_id 
                      INNER JOIN 
                                `tabelle_1` ON tabelle_4.ort_id = tabelle_1.ort_id 
                      AND 
                                `tabelle_3` ON tabelle_4.user_id = tabelle_3.user_id 
                      WHERE 
                                `status` = '1' 
                      AND 
                                `ort_id` = '$id'                      
"; 
$result = mysql_query($sql_query); 
while( $row = mysql_fetch_array($result,MQSQLASSOC) ) { 

echo $row['ort_id']."<br />"; 
echo $row['ort_name']."<br />"; 
echo $row['anbieter_id']."<br />"; 
echo $row['anbieter_bezeichnung']."<br />"; 
echo $row['user_id']."<br />"; 
echo $row['user_name']."<br />"; 
echo $row['vertrag']."<br />" 
} 
...
```

*@ CraisiePrinzZ:*
habe beide Vorschläge von Dir leider erfolglos versucht. Da ist immer noch irgendein Wurm drin, der sich hartnäckig vor mir versteckt! 


Beste Grüße,
preko


----------



## Biber2 (10. Januar 2008)

Moin preko,

kann aber auch viel banaler sein...

```
INNER JOIN  
                                `tabelle_2` ON tabelle_4.anbieter_id = tabelle_2.anbieter_id  
                      INNER JOIN  
                                `tabelle_1` ON tabelle_4.ort_id = tabelle_1.ort_id  
                      AND  
                                `tabelle_3` ON tabelle_4.user_id = tabelle_3.user_id
```

Der erste INNER JOIN... okay.
Der zweite...ist wo genau zu Ende?  Nach ".... ort_id" ?
Und was soll das nach dem "AND" sein? Doch eher eine "WHERE"-Bedingung.
Dann gehört es aber ein paar Zeilen tiefer mit dazu.

Grüße
Biber


----------



## olqs (10. Januar 2008)

Hab vielleicht noch was gefunden:

Welchen Typ hat denn die Status Spalte in Tabelle1?

Wenns eine Integer Spalte ist, dann musst du die Hochkommas um die 1 entfernen:

```
WHERE status = 1
```


----------



## preko (10. Januar 2008)

H Biber2,



Biber2 hat gesagt.:


> ```
> // 1. JOIN
> INNER JOIN
> `tabelle_2` ON tabelle_4.anbieter_id = tabelle_2.anbieter_id
> ...



*@ olgs:*
Die Spalte "*Status*" ist eine vom Typ "*Integer*".


Beste Grüße,
preko


----------



## dummdidummoei (10. Januar 2008)

```
SELECT
	tabelle_1.ort_id AS ort_id,
	tabelle_1.ort_name AS ort_name,
	tabelle_2.anbieter_id AS anbieter_id,
	tabelle_2.anbieter_bezeichnung AS anbieter_bezeichnung,
	tabelle_2.ort_id,
	tabelle_3.user_id AS user_id,
	tabelle_3.user_name AS user_name,
	tabelle_4.ort_id,
	tabelle_4.anbieter_id,
	tabelle_4.user_id,
	tabelle_4.vertrag AS vertrag
	FROM
		`tabelle_4`	
			INNER JOIN	`tabelle_2` ON (tabelle_4.anbieter_id = tabelle_2.anbieter_id)
			INNER JOIN	`tabelle_1` ON (tabelle_4.ort_id = tabelle_1.ort_id)
			INNER JOIN	`tabelle_3` ON (tabelle_4.user_id = tabelle_3.user_id)
			WHERE	`status` = '1'	AND	`id` = '$id'
```

versuchs so


----------



## preko (11. Januar 2008)

*@ dummdidummoei:*

leider funktioniert es nicht. Der letzte der drei INNER JOIN macht die Probleme. Nehme ich diesen heraus, kriege ich eine, wenn auch unvollständige Darstellung, da ja einige Daten nicht vorhanden sind, die aus der dritten Abfrage kämen.

Sobald der dritte INNER JOIN wieder reingesetzt wird, kommt erneut die Fehlermeldung:


> *Warning:* mysql_fetch_array(): supplied argument ist not a valid MySQL result resource in D:\nur\ein\projekt.php on line ....



Gibt es vielleicht irgendwie eine Limitierung auf 2 INNER JOIN Anweisungen, die an mir vorbeigegangen ist? 


Beste Grüße,
preko


----------



## aGeNET (11. Januar 2008)

Ich nochma,

Das ganze mal ohne JOIN, ist zwar nicht so schön, aber leichter zu überschauen

```
SELECT * FROM `tabelle_1`, `tabelle_2`, `tabelle_3`, `tabelle_4`
WHERE `tabelle_4.anbieter_id` = `tabelle_2.anbieter_id`
AND `tabelle_4.ort_id` = `tabelle_1.ort_id`
AND `tabelle_4.user_id` = `tabelle_3.user_id`
AND `tabelle_4.ort_id` = '$id'
AND `tabelle_4.status` = '1' 
/* bzw `tabelle_4.status` = 1 // nicht vergessen, beim `status` die genaue Tabelle anzugeben. ich nehme mal an es ist die 4. */
```


Nur noch ein kleiner Rat:
Versuch dir anzugewöhnen, die Tabellen und deren Felder besser auseinanderzuhalten.
Das Ganze geht relativ einfach, in dem du den Tabellen eindeutige Namen gibst und in der jeweiligen Tabelle jedes Feld mit dem Tabellenname beginnst.

Bsp:

```
tabelle_1 -> orte
-------------------------
ort_id | ort_name


tabelle_2 -> anbieter
------------------------------
anbieter_id | anbieter_name | anbieter_ort


tabelle_3 -> user
-------------------------
user_id | user_name ( | user_ort)

tabelle_4 -> vertrag
-------------------------
vertrag_id | vertrag_anbieter_id | vertrag_user_id | vetrag_beschreibung | vertrag_status
```

Kannst dich ja auch noch besser in das Normalisierung einarbeiten, es erleichtert die Arbeit mit Datenbanken ungemein.
mfg


----------



## preko (15. Januar 2008)

*@ aGeNET:*

danke für die Antwort. Die Tabellen sind tatsächlich anders (eindeutig) benannt. Habe aus bestimmten Gründen die Namensänderung vorgenommen. 

Werde es mal mit Deinem Vorschlag versuchen.


Beste Grüße,
preko


----------



## preko (15. Januar 2008)

Sorry, Doppelposting. Hatte eine Netzwerkfehlermeldung beim Speichern erhalten.

Bitte löschen falls möglich.


Beste Grüße,
preko


----------



## Dr Dau (15. Januar 2008)

Hallo!

[off]


preko hat gesagt.:


> Bitte löschen falls möglich.


Möglich ja, aber überflüssig.
Wenn der Beitrag gelöscht wird, dann bleibt zumindest ein Hinweis darüber zurück dass er gelöscht wurde.
Es sollte also zumindest der Grund des löschens genannt werden, damit auch die Nachwelt bescheid weiss.
Somit ist es aber Jacke wie Hose ob der Beitrag nun gelöscht oder einfach nur editiert wird. 
Letzteres hast Du gemacht und dabei auch den Grund genannt und Dich entschuldigt, somit ist das Thema auch für die Admins/Mods gegessen. 

Im übrigen kannst Du den Beitrag (aber nur Deinen eigenen) auch selbst löschen.
Dazu musst Du einen Rechtsklick auf den "Ändern"-Button machen und im neuen Fenster/Tab öffnen, dann bekommst Du auch die Option zum löschen.
Macht aber aus schon oben genannten Gründen keinen Sinn.
[/off]

Gruss Dr Dau


----------



## preko (23. Januar 2008)

@ aGeNET:

habe es wie von Dir zuletzt vorgeschlagen versucht, allerdings wieder ohne Erfolg. Bekomme immer noch die dusselige Fehlermeldung:



> *Warning:* mysql_fetch_array(): supplied argument ist not a valid MySQL result resource in ...



Ich verzweifel langsam... 

Es muß doch eine Lösung geben! Bin für jeden "Strohhalm" dankbar! 


Beste Grüße,
preko


----------



## Biber2 (23. Januar 2008)

Moin preko,

nun lass uns doch erstmal ein Thema zu ende machen... <grinz>
Der von Dir gepostete Fehler liegt bestimmt daran, dass der zweite Parameter der mysql_fetch_array(), nämlich MYSQLASSOC nicht als Konstante definiert ist bzw in Deiner Schreibweise nicht erkannt wird.
Gemeint ist bestimmt MYSQL_ASSOC (mit Unterstrich).
Während Du oben stehen hast "while( $row = mysql_fetch_array($result,MQSQLASSOC) ) { ..."

Aber das hat nichts mit der Richtigkeit von aGeNETs Statement zu tun.

Grüße
Biber


----------



## preko (23. Januar 2008)

*@ Biber2:*

für einen Biber schon Adlerscharfe Augen. Sorry, ich habe im Ursprungsporting einen Tippfehler gehabt, den ich in späteren Posts per Drag`n Drop übernommen habe.

Natürlich heisst die Zeile bei mir richtig:


> "while( $row = mysql_fetch_array($result,*MYSQL_*ASSOC) ) { ..."



Man sollte auch nicht immer so hastig schreiben... 

Das schließt also die Fehlermeldung im Bezug auf diesen Punkt wohl aus.


Beste Grüße,
preko


----------



## aGeNET (23. Januar 2008)

mhh das ärgert mich natürlich auch, dass dir mein Vorschlag nicht weiterhilft.
Kannst du mal deine aktuelle Struktur der betroffenen Datenbank-Tabellen posten? Vielleicht findet sich da noch was. Muss doch ne Lösung für das Problem geben.

mfg


----------

