Hallo!
Ich habe folgendes Problem:
es gibt 2 Tabellen in meiner Datenbank:
person:
id|name|geschlecht
1 |jule|weiblich
2 |hans|männlich
und
sprache:
id|sprache|person_id
1|engl. |1
2|franz. |1
3|jap. |1
4|deut. |2
Ich hätte gerne eine SQL-Abfrage, die mir pro Person in _einer_ Zeile folgende Attribute zurückliefert:
person_id|name|geschlecht|sprache1|sprache2|…
Von mir aus auch auf einen Maximal-Wert für die Anzahl der Sprachen beschränkt.
Existiert soetwas für MySQL 4.0?
Eigentlich müßte das doch ein häufiges Problem sein, hat jemand zufällig dafür eine Lösung parat?
Danke schön!!
wärs nicht einfacher sprache bei person mit reinzupacken?
Ich glaube, es geht nur so:
person_id|name|geschlecht|sprache1
1|jule|weiblich|(1|engl.)
1|jule|weiblich|(2|franz.)
1|jule|weiblich|(3|jap.)
2|hans|männlich|(4|deut.)
oder?
Tomek
mit SQL hat dieses Standardproblem wohl nix zu tun,
das muss man sich eigentlich selber zusammenbasteln auf einer höheren Ebene
wenns unbedingt in der DB passieren soll: in diesem Fall vielleicht ein Join von Tomek's Tabelle mit sich selber über die person_id mit Umbenennung der Sprachspalte reduziert auf zwei unterschiedliche Sprachen,
bei drei Sprachen wärs ein Dreifach-Join usw.
mit verschiedenen spalten wüsste ich nicht wie, was du aber machen kannst, ist GROUP BY person_id und dann mit GROUP_CONCAT(sprache) alle sprachen aneinanderhängen, das musst du dann in der andwendung wieder auseinanderflücken, weiss ja nicht was du damit machen willst.
Im Grunde ist das ganze ganz einfach:
Deine Abfrage könnte beispielsweise mit PHP erfolgen.
Dabei lässt eine Tabelle sequentiell durchgehen und suchst mit dem gemeinsamen Nenner (hier der Name) dann in der anderen Tabelle die entsprechenden Daten und gibst dieses gemeinsam aus.
Wenn es Dir zu schwer wird das in einer Ausgabe zu machen kannst Du ja auch mit einem Array arbeiten…
Alles klar?? ;)
Danke erstmal für die vielen Antworten!
GROUP_CONCAT und ein späteres explode wäre tatsächlich eine Möglichkeit. Leider gibt es das erst ab MySQL 4.1 [img]
http://www.fb18.de/gfx/seufz.gif[/img]
Problematisch ist die höhere Ebene (PHP etc.) halt bei großen und komplexen Datensätzen. Da geht dann die Performanz ganz schnell flöten.
Naja, am Ende sollte man wirklich auf Normalformen für DBs verzichten und alles machen wie früher…
Was du versuchst heisst "pivot" oder "crosstab" query. Ist in mysql etwas umstaendlich, aber (in etwas abgewandelter Form) moeglich.
Mir faellt spontan eine Loesung ein, die dir folgendes Resultset liefert:
id, name, geschlecht, deutsch, englisch, spanisch, …
1, "person1", m, 1, 0, 1, ….
2, "person2", f, 0, 1, 1, ….
3, "person3", f, 1, 1, 0, ….
Du haettest also fuer jede Sprache eine "boolean" Spalte.
Um dieses Resultset zu erzeugen brauchst du 2 Queries und etwas String manipulation in einer extenen Sprache.
Erster Query: SELECT DISTINCT sprache FROM sprache;
(Die Tabellen/Spaltennamen sind etwas ungluecklich gewaehlt imho…)
Aus diesem Query erstellst du mit PHP oder so einen Query der folgenden Form:
SELECT
person.id,
person.name,
person.geschlecht,
COUNT(CASE sprache = 'deutsch' THEN person.id ELSE NULL END) as deutsch,
COUNT(CASE sprache = 'englisch' THEN person.id ELSE NULL END) as englisch,
COUNT(CASE sprache = 'spanisch' THEN person.id ELSE NULL END) as spanisch,
...
...
FROM
person,
sprache
WHERE
person.id = sprache.person_id
GROUP BY
person.id,
person.name,
person.geschlecht;
Fuer jede $SPRACHE in der DB kommt also ein weiteres COUNT(… sprache = '$SPRACHE') AS $SPRACHE_COLUMN_NAME hinzu. Den Query schickst du zur Datenbank, fertig.
Das sollte recht performant sein, solange die Anzahl der moeglichen Sprachen nicht ausufert. Auf jeden Fall schneller als die Daten später mit PHP oder ähnlichem zu kombinieren.
Die Sprachen selbst sollten natuerlich "mysql sicher" sein, also kein User input => mysql injection.
Hoffe das hilft. Google hilft sicher auch wenn du nach "pivot query" oder "crosstab query" suchst.