Problem mit MySQL-Abfrage

baserider

Well-known member
ID: 174417
L
10 März 2007
682
23
HI,

folgendes Problem:

Es gibt 3 Tabellen:

produkt:
- pk
- name

kategorie:
- pk
- name

produkte_kategorien
- pk
- produkt_fk (Fremdschlüssel)
- kategorie_fk (Fremdschlüssel)

Jedes Produkt kann mehrere Kategorien zugeordnet werden. Ich habe bereits eine Abfrage, die mir alle Kategorien zu einem Produkt anzeigt.

Mein Problem, ich brauchte eine Abfrage, die mir alle Kategorien anzeigt, auch wenn ein Produkt nicht dieser kategorie zugeordnet ist

Das Ergebnis sollte dann ungefähr so aussehen:

Kategorie A -- Produkt A
Kategorie B -- Produkt A
Kategorie C -- NULL (da Produkt A nicht Kategorie C zugeordnet ist)

Ich dachte es geht mit nem Left-Join aber bringt irgendwie nix.
das gibt mir alle Kategorien zu einem Produkt, aber eben nicht alle Kategorien auch wenn das Produkt der Kategorie NICHT zugeordnet ist

Code:
SELECT p.*, k.* FROM produkt p
INNER JOIN produkt_kategorie pk ON pk.produkt_fk = p.pk
INNER JOIN kategorie k ON pk.kategorie_fk = k.pk
WHERE p.pk = 200
 
Was genau willst du denn haben? Eine Liste mit allen Kategorien und eine Angabe, ob ein bestimmtes Produkt der jeweiligen Kategorie zugeordnet ist?
 
Ich verstehe es auch nicht so ganz, eigendlich müsste die tabelfix es recht so hinbekommen wie du es möchtest, aber wie mister_nu schon sagte etwas genauer bitte, ThX :)
 
Was genau willst du denn haben? Eine Liste mit allen Kategorien und eine Angabe, ob ein bestimmtes Produkt der jeweiligen Kategorie zugeordnet ist?

ganz genau... ich habs bisher nur mit 2 abfragen geschafft, und auch nen left join geht nicht...keine ahnung ob überhaupt geht :)

so gehts auch nicht:
Code:
SELECT p.*, k.* 
FROM kategorie k 
LEFT JOIN produkt_kategorie pk ON pk.kategorie_fk = k.pk
LEFT JOIN produkt p ON pk.produkt_fk = p.pk
WHERE p.pk = 200
 
Wenn du alle willst, darfst die nciht nur auf die Zeilen eingrenzen, die das produkt beinhalten, also so:

WHERE p.pk = 200 or p.pk is null
 
Intuitiv (also ohne ausprobieren) würde ich sagen:

Code:
SELECT p.*, k.* FROM kategorie k LEFT JOIN produkt_kategorie pk ON pk.kategorie_fk = k.pk LEFT JOIN produkt p ON pk.produkt_fk = p.pk WHERE pk.produkt_fk = 200 OR pk.produkt_fk IS NULL
 
Versuch mal

PHP:
Select *
From Kategorie K
LEFT JOIN
( SELECT P.*, PK.kategorie_fk as KFK
FROM produkt_kategorie PK inner join produkt P
ON PK.Produkt_fk = P.pk 
WHERE P.PK = 200 ) J
ON K.PK = J.KFK

diese Abfrage brauchst Du allerdings nur dann, wenn Du zu den Kategorieninfos auch Daten des Produktes haben willst. Wenn Du nur wissen willst ob es das Produkt für die Kategorie gibt oder nicht und die ProduktID bekannt ist, dann brauchst Du nur die Kategorie-Tabelle mit der Produkt_Kategorie zu joinen:

PHP:
SELECT *
FROM kategorie K
LEFT JOIN 
( SELECT kategorie_FK 
from produkt_kategorie 
WHERE Produkt_FK = 200 ) PK
ON  K.ID = PK.kategorie_FK


Einige Datenbanksysteme können sogar sowas im Join-Kriterium verdauen, leider weiss ich nicht, ob MySQL dazugehört:

PHP:
SELECT * 
FROM kategorie K
LEFT JOIN 
produkt_kategorie PK
ON  K.ID = PK.kategorie_FK
AND PK.Produkt_FK = 200


selbstverständlich sollte man niemals in der fertigen Query "SELECT *" schreiben, sondern explizit die Spalten angeben, die man benötigt
 
Zuletzt bearbeitet:
@transversalis

danke dir...die letzten beiden Varianten klappen, wobei ich die letzte nehmen werden, da kürzer :) dort kann ich ja bei bedarf ebenfalls noch produktdaten ausgeben, aber ich brauche es in diesem falle nicht.

Jetzt is das Ergebnis aber korrekt :) An AND bzw. den Subselect habe ich garn icht gedacht bzw. auch nicht gewusst das das so geht...gibts da im netz irgendwo paar gute Sachen zum Nachlesen?

ich war mir sicher mit

Code:
SELECT p.*, k.* 
FROM kategorie k 
LEFT JOIN produkt_kategorie pk ON pk.kategorie_fk = k.pk
LEFT JOIN produkt p ON pk.produkt_fk = p.pk
WHERE p.pk = 200

klappts, weil ich auch schon andere Abfragen so gemacht habe. leider funktioniert das hier nicht.