# MySQL joins auf mehrere tabellen



## momo006 (3. November 2007)

Hallo zusammen,

angemeldet im forum und schon ein problem 
aber ich helf anderen auch gern.

ich habe folgendes problem mit joins. vorweg erstmal dies:

TABELLE 1
|hersteller|
---------------
|h_id | Firmenname

TABELLE 2
|hersteller_produkte|
-----------------------------
|p_id | h_id | cat_id| Produktname

TABELLE 3
|hersteller_assoc|
-------------------------
|h_id | cat_id |

TABELLE 4
|kategorien|
-----------------
|cat_id | cat_name | parent_id

nun möchte ich folgendes auslesen.
Firmenname - Kategorie - Produktname. 


```
select hersteller.Firmenname
from hersteller, hersteller_assoc as AC
where AC.h_id = hersteller.id 
and AC.cat_id = 446 order by hersteller.Firmenname ASC
```

hiermit kann ich alle auslesen die eben in einer bestimmten cat_id sind. das tut auch. nur hat hier z.b. nicht jeder der firmen ein produkt. wenn eines vorhanden soller auch noch den produktnamen ausgeben. es kann ggf. auch sein das eine firma mehrere produkte hat.

nun meine frage: wie mach ich das mit einem join? left join oder inner join?
muss ich nochmals eine sog. lookup-table anlegen wo ich hersteller mit produkt verknuepfe? die TABELLE 3 verknüpft im moment nur TABELLE 1 mit TABELLE 4.
in der produkt-table stehen dann, wenn es ein neues produkt zu einer spez. kategorie und firma gibt, eben die nummern drin. diese tabelle hat keine lookup.

danke für Eure hilfe.


----------



## momo006 (4. November 2007)

momo006 hat gesagt.:


> Hallo zusammen,
> ....
> danke für Eure hilfe.



mmmhhhh - hab gestern noch probiert - irgendwie scheint es nicht zu tun.

oder geht es nur mit subselects ? leider hab ich nur mysql 4.x.x



keiner da, der mir ggf. einen kleinen denk-anstoss geben koennte? oder ein tipp?

danke


----------



## Online-Skater (4. November 2007)

Probier mal folgendes


```
SELECT `a`.`Produktname`,`b`.`Firmenname`,`c`.`cat_name`
FROM `a`.`hersteller_produkte`
LEFT JOIN `b`.`hersteller` USING(`h_id`)
LEFT JOIN `c`.`kategorien` USING(`cat_id`)
ORDER BY `b`.`hersteller`;
```

Ungetestet aber denke mal die assoc Tabelle ist überflüssig.

mfg;-)


----------



## momo006 (4. November 2007)

Online-Skater hat gesagt.:


> Probier mal folgendes
> 
> 
> ```
> ...



neee, geht net 

folgendes:

mysql> select p_id, h_id, cat_id from hersteller_produkte;
+------+------+--------+|
 p_id | h_id | cat_id |
+------+------+--------+|
|  43 |  633 |    446  |
|  37 |  427 |   1101 | 
usw....

p_id = prim_key. hier sind hersteller drin und die entsp. kategorie.

nun möchte ich alle hersteller ausgeben die 1) kein produkt haben und 2) die die eines haben und dann die p_id ausgeben zur weiteren verwendung. (kann auch produkname sein).

mit folgenem join bekomm ich hin, das er mir alle sucht die ein produkt haben.


```
select
P.produktname, P.p_id, H.Firmenname, H.id , C.cat_name, P.cat_id, P.h_id
from
hersteller_produkte as P
left join hersteller as H on (P.h_id = H.id)
left join hersteller_kategorien as C on (P.cat_id = C.cat_id)
```

nun sind aber in der hersteller_assoc tabelle aber auch firmen verknüpft mit einer kategorie und diese firmen haben keine produkte. diese sollen auch ausgeben werden.

ich dachte da an folgendes:


```
select
P.produktname, P.p_id, H.Firmenname, H.id , C.cat_name, P.cat_id, P.h_id
from
hersteller_produkte as P
left join hersteller as H on (P.h_id = H.id and P.cat_id = 2194)
left join hersteller_kategorien as C on (P.cat_id = C.cat_id)
```

hier bekomm ich jetzt wieder alle firmen raus die ein produkt haben. aber da ich eine feste cat_id mitgebe, findet er jetzt nur die eine firme eben die unter dieser kategorie ein produkt hat.



irgendwie scheint das was ich gerne möchte nicht zu tun.

:suspekt:
vllt. nochmal auf erzählform.
"ich möchte gerne alle firmen auflisten, die in einer speziellen kategorie sind. liste diese auf und wenn eine firma dann ein produkt hat, gebe mir z.b. den produktnamen aus und die kategorie dazu und sortier mir das dann an die erste stelle."

hoffe das ich es gut erklaert hab.

danke

momo


----------



## momo006 (4. November 2007)

momo006 hat gesagt.:


> neee, geht net
> ...
> momo



ergänzug - man probiert ja immer selber bevor man um hilfe schreit.

mit folgenem bekomm ich nur die firma raus, die ein produkt in einer bestimmten kategorie hat:


```
select 
hersteller.Firmenname, hersteller_produkte.p_id, hersteller.id as h_id, hersteller_produkte.cat_id, hersteller_kategorien.cat_name
from 
hersteller, hersteller_produkte, hersteller_kategorien, hersteller_assoc as AC 
where 
AC.h_id = hersteller.id and AC.cat_id = hersteller_produkte.cat_id 
and AC.h_id = hersteller_produkte.h_id
and AC.cat_id = hersteller_kategorien.cat_id 
and hersteller_produkte.cat_id = 2194
```

hiermit bekomm ich schnell alle hersteller einer bestimmten kategorie raus:


```
select hersteller.Firmenname
from hersteller, hersteller_assoc as AC
where AC.h_id = hersteller.id 
and AC.cat_id = 2194
```

nun muss ich aber diese beiden abfragen zusammen legen - oder muss ich da nochmals n select inner while schleife machen?

in etwa so:


```
$cmd = erstes sql statement;

   while (erstes sql) {

      $cmd2 = zweites sql statement;

   }
```



danke

gruss
momo


----------



## momo006 (4. November 2007)

momo006 hat gesagt.:


> ergänzug
> ...



oder ist dies die elegante super lösung?


```
select hersteller.Firmenname, P.produktname
from hersteller, hersteller_assoc as AC
left join hersteller_produkte as P on (P.cat_id = AC.cat_id and P.h_id = hersteller.id)
where AC.h_id = hersteller.id 
and AC.cat_id = 446 
order by P.p_id desc
```


----------



## Quick_Mik (7. November 2007)

Hallo,

Du musst das Ding in der FROM Klausel auf jeden Fall vom Hersteller aus angehen, den du willst ja auch die Firmen, bei welchen noch keine Produkte da sind.
Danach müssen LEFT JOINs rein, da die erste Tabelle (also die linke) die nicht optionale ist.
Versuch mal

```
select
hersteller.firmennae, kategorien.cat_name,hersteller_produkte.produktname
from
hersteller
left join hersteller_produkte on hersteller_produkte.h_id = hersteller.h_id
left join kategorien on kategorien.cat_id = hersteller_produkte.cat_id
```
Ungetestet, sollte aber gehen 
Ich schließe mich bezüglich der Kreuztabelle Online-Skater an, die kannst Du rauswerfen; is nur Ballast.

Gruß

M.


----------

