LEFT JOIN: 2 Zeilen, 1 Spalte auslesen
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
array
ausbildung
ausbildungsbereich
ausgabe
bearbeiten
bereich
bestanden code
brauche
code
grad
hinzukommen
lauf
mache
ohr
person
spalte
string
tabelle
vorhanden bereich
zeile
-
Hallo zusammen!
Ich probiere mich nach langer Zeit wieder an SQL und bearbeite ein altes Projekt. Jetzt habe ich ein Problem und weiß einfach nicht, wie ich es lösen kann:
Ich habe eine Tabelle t_person, in der ich Name, E-Mail, etc. zu einer Person habe.
id_pers | name_pers | email | ... 5 | Thomas | t@om.as | ...
Dann gibt es die Tabelle t_education, in der die fünf möglichen Ausbildungsbereiche vermerkt sind.
id_edu | name_edu 1 | Grundausbildung 2 | Fortgeschrittene 3 | Gruppentraining
Eine Person kann alle Bereiche im Lauf der Zeit "bearbeiten" und ich brauche auch jeden Bereich, in den die Person sich mal eingeschrieben hat. Dafür habe ich eine Schlüsseltabelle st_edupers erstellt:
id_edupers | pers_id | edu_id
Soweit war ich mit meinem System zufrieden. Jedoch hat jede Person für jeden Ausbildungsbereich einen gewissen Prüfungslevel. Somit kann bei 5 Ausbildungsbereichen jede Person 5 verschiedene Prüfungslevel haben. Und wenn mehr Bereiche hinzukommen natürlich auch mehr Prüfungslevel. Eine Person könnte jedoch auch nur einen oder gar keinen Prüfungslevel haben.
"grade" habe ich darum jetzt mal in die st_edupers-Tabelle gesetzt. Jede Zeile ist eine Person-Ausbildungsbereichs-Kombination - und genau soviele Prüfungslevel hat die Person. Erschien mir genial (für meine Verhältnisse...).
Die Tabelle st_edupers ist nun:
id_edupers | pers_id | edu_id | grade 4 | 5 | 1 | 6 5 | 5 | 3 | 9
Jetzt weiß ich nur nicht, wie ich an die ganzen Zeilen rankomme.
Ich arbeite grade an der Ausgabe des Personenprofils und bei der Ausgabe von Ausbildung und Prüfungslevel bekomme ich nun natürlich immer nur die erste Zeile. Wie kann ich alle Zeilen, die die Person enthalten aufgreifen und die verschiedenen Werte von edu_id und grade im Template nutzen?
Mein aktuelles SQL (nur die relevanten Werte):
SELECT t_person.id_pers, st_edupers.grade FROM t_person LEFT JOIN st_edupers ON t_person.id_pers = st_edupers.pers_id WHERE t_person.id_pers = 5
Fürs Template:
(isset($data->grade)) ? $grade = $data->grade : $grade = "noch keine Prüfung bestanden";
Muss ich beim LEFT JOIN nun noch ein "AND-ON-SELECT"-Konstrukt oder so etwas machen? Wie mache ich das mit der Variablenzuweisung, wenn ich mehrere Werte aus der Spalte "grade" brauche?
Ich würde mich sehr freuen, wenn mir jemand auf die Sprünge helfen könnte. Vielleicht ist meine Tabellenverteilung auch Mist, aber ich weiß grad nichts eleganteres... :/
Vielen Dank schon einmal!
Grüße
things
EDIT:
So, nun habe ich mir die ganze Nacht um die Ohren geschlagen und sicher ein paar graue Haare ergrübelt! Aber ich habe eine Lösung. Wenn ihr elegantere/performantere Wege kennt, bin ich immer noch ganz Ohr :)
Die Funktion GROUP_CONCAT fasst die Ergebnisse aus verschiedenen Zeilen einer Spalte zu einem String zusammen. Ich benutze sie jetzt bei den Spalten edu_id und grade:
SELECT t_person.id_pers, GROUP_CONCAT(st_edupers.edu_id SEPARATOR '#%') as eduids, GROUP_CONCAT(st_edupers.grade SEPARATOR '#%') as edugrades, FROM t_person LEFT JOIN st_edupers ON t_person.id_pers = st_edupers.pers_id WHERE t_person.id_pers = 5
Die Strings trenne ich mit explode. Dann habe ich ewig an den Arrays verbracht und combine() und array_merge_recursive() ausprobiert. Ich wollte eine Arraystruktur a la "edu_id ("grade" : "4", "foo" : "bar", ...)" - hat leider nicht geklappt. Mit 3 Werten konnte ich das nicht realisieren, darum mache ich nun ein neues Array und setzte dort die Werte ein:
$eduids = explode("#%", $data->eduids); $edugrades = explode("#%", $data->edugrades); $edufoos = explode("#%", $data->edufoos); $education = array(); if(count($eduids) > 1) { foreach($eduids as $key => $value) { $education[$value] = array("grade" => $edugrades[$key], "foo" => $edufoos[$key]); }; } else { //just one education $education[$eduids[0]] = array("grade" => $edugrades[0], "foo" => $edufoos[0]); }
Damit erhalte ich ein Array $education, in dem alle Informationen zu den bearbeiten Bereichen enthalten sind. Auf einen bestimmten Bereich greife ich durch den Index des Arrays zu (hier sind nur $education[1] und $education[3] vorhanden - Bereich 2 wurde nicht bearbeitet). Für die Ausgabe des Levels nutze ich dann $education[3]["grade"]. Wenn ich Inhalte nur ausgebe, wenn der Bereich bearbeitet wurde, reicht ein isset($education[5]).
Bisher funktioniert es gut und ich bin ziemlich happy ^^ Ich hoffe, dass das hier auch einmal einem anderen Suchenden weiterhilft. :)
Beitrag zuletzt geändert: 16.11.2013 14:19:57 von things -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage