PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Alle Kategorien zu einem Item in einer SQL-Abfrage sammeln


jospanier
05.01.2006, 12:46:39
Hallo zusammen,

Ich habe folgendes Problem. Meine Datenbank sieht so aus:

items:
item_id|item_name
1|foo
2|bar

cat:
cat_id|cat_name
1|grün
2|rot
3|Obst
4|Gemüse

items2cat:
item_id|cat_id
1|1
1|3
2|1
2|4

Also eine n:m-Beziehung zwischen Item und Kategorien.

EDIT: Ein "LEFT JOIN" würde mir die Datensätze (fast) passend verknüpfen.

Ich will jetzt aber mit einer SQL-Abfrage eine Tabelle erhalten die so aussieht:

item_id|item_name| <Liste ALLER zugeordneten Katgorien>
1|foo|grün,Obst
2|bar|rot, Gemüse

EDIT: Also alle Kategorien zu einem Item in einer Zelle. Ein einfaches "JOIN" liefert hier aber leider nicht das von mir gewünschte Ergebniss.

Ist das mit mySQL und reinem SQL machbar, oder muss ich das in PHP machen ?


Gruß,
Johannes

diver-network
05.01.2006, 13:06:16
Hi,

ohne die Lösung zu verraten:

Die Lösung heißt "JOIN". Sprich: Du kannst das alles per SQL, sprich auf der Datenbank machen. Anzeigen geht natürlich nur per PHP ;-)

Such einfach mal im Forum danach und Du wirst vermutlich 100e von Einträgen hierzu finden.
Ist aber eigentlich SQL Einführung, 1. Stunde bzw. 1. Kapitel.


HTH,

Andy

EDIT: Die Formatierung ( 1|foo|grün,Obst) bekommst Du vermutlich einfacher per PHP hin. Per (My)SQL bekommst Du vor allem die passenden Datensätze.

jospanier
05.01.2006, 14:34:30
Hi,

Wir kommen der Sache näher.
Natürlich weiss ich, dass ich mit

"SELECT * from items LEFT JOIN items2cat USING (item_id) LEFT JOIN cat USING (cat_id)"

meine Tabellen (fast) geeignet verknüpft bekomme. (So blutig bin ich dann doch nicht mehr).

Aber leider sieht das Ergebniss dann so aus:
1|foo|grün
1|foo|Obst
2|bar|rot
2|bar|Gemüse

Ich will aber (am liebsten in reinem SQL), dass die Kategorien alle in einer Spalte hinter dem jeweiligen Item auftauchen (s.o.). Also so wie die Datenbank vor allen Normalisierungen ausgesehen hätte.

Kennt jemand eine Lösung in reinem (my)SQL oder muss ich hier mit PHP in einer Schleife über die einzelnen Items jeweils für jedes Item die Kategorien aus der DB abfragen. Das wären bei einer Datenbank mit 100ten von Sätzen 100te von SELECTs, was ich für eher unelegant halte. Gibt es vielleicht eine Lösung in PHP die mit dem Ergebniss der JOINS das von mit gewünschte Ergebniss bringt?

Gruß,
Johannes

Marilu
05.01.2006, 20:07:08
Ich würde eine PHP-Lösung so machen: Das von Dir erhaltene Resultset einmal durchlaufen und in einem Array die gewünschte Struktur ablegen. Danach mußt Du einmal das Array durchlaufen und als Tabelle ausgeben.

jospanier
06.01.2006, 13:57:42
Hi,

Ich hab mal noch ein wenig woanders gestöbert. Seit Version 4.1 gibt es bei MySQL die Aggregate Funktion "GROUP_CONCAT(expr)", die genau daß macht, was ich erreichen will.

Das sieht dann so aus:

"SELECT items.*, GROUP_CONCAT(cat_name) from items LEFT JOIN items2cat USING (item_id) LEFT JOIN cat USING (cat_id) GROUP BY item_id"

Ergebnis:
1|foo|grün,Obst
2|bar|rot,Gemüse

Das "GROUP BY" darf nicht weggelassen werden. Die Einträge (hier cat_name) die zu der gleichen Gruppe gehören werden zusammengefasst.

Gruß,
Johannes

Marilu
06.01.2006, 14:12:39
Schön gemacht ... wenn man nur auf jedem Server MySQL 4.1 hätte! :-(((