SELECT INNER JOIN aus einer Tabelle


#1
Moinsen!

Ich würde gern aus einer einzigen Tabelle (usermeta) spezifische Daten auslesen. Die Tabelle ist nur leider nicht in Spalten, sondern in Zeilen aufgebaut und da die Struktur leider nicht verändert werden kann, frage ich nun mal hier, wie ich das anstellen könnte.

Ich habe den unten stehenden Weg versucht, jedoch wird mir auf diese Weise der erste Nachname aus "n" in jeglichen Output geschrieben. Ich möchte auch noch weitere Zellen auslesen, als nur Vor und Nachname. Ich bin da nur leider nicht so ganz auf meinem Gebiet und frage deshalb mal auf diesem Wege. Für jegliche Vorschläge/Hilfe wäre ich sehr dankbar!


PHP:
$sql = "
SELECT m.user_id AS 'id',
m.meta_value AS 'Vorname',
n.meta_value AS 'Nachname'
FROM
usermeta m
INNER JOIN
usermeta n
WHERE
m.meta_key = 'first_name' AND n.meta_key = 'last_name'
GROUP BY
id";
$result = $conn->query($sql);

if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
        echo "<br> id: ". $row["id"]. " - Name: " . $row["Vorname"]. " " . $row["Nachname"]. " <br>";
    }
}
else {
    echo "0 results";
}
 

Yaslaw

n/a
Moderator
#3
Du brauchst keinen JOIN sondern ein CASE oder IF()
Ich habe hier mal drei verschiedene Möglichkeiten. Ich rate aber vom IF() ab, da der MySQL-Spezifisch ist. Wenn du mal zu Oracle oder anderen DBA wechseln willst, bist du mit CASE besser bedient
SQL:
SELECT
   u.user_id AS id,
   MAX(CASE u.meta_key WHEN 'first_name' THEN u.meta_value ELSE NULL END) AS vorname,
   MAX(CASE WHEN u.meta_key = 'last_name'  THEN u.meta_value ELSE NULL END) AS nachname,
   MAX(IF(u.meta_key = 'street', u.meta_value, NULL)) AS strasse
FROM
   usermeta u
GROUP BY
   i.user_id
 
#4
Super! Vielen Dank - das hat schon mal gut geklappt. :) Ich habe die zweite Variante von Dir gewählt und das funktioniert prima:

SQL:
SELECT
    u.user_id AS 'id',
    MAX(CASE WHEN u.meta_key = 'first_name' THEN u.meta_value ELSE NULL END) AS 'Vorname',
    MAX(CASE WHEN u.meta_key = 'last_name' THEN u.meta_value ELSE NULL END) AS 'Nachname',
    MAX(CASE WHEN u.meta_key = 'plz_search' THEN u.meta_value ELSE NULL END) AS 'PLZ',
    MAX(CASE WHEN u.meta_key = 'member_ort' THEN u.meta_value ELSE NULL END) AS 'Ort'
FROM
    usermeta u
GROUP BY
    id
Wenn mir jetzt noch jemand helfen könnte, wie ich die Daten aus einer anderen Tabelle integrieren kann, wäre mein Tag gerettet. (Ich habe leider eben erst gemerkt, dass die Mails in einer anderen Tabelle gespeichert wurden...)

Dort möchte ich allerdings eine Spalte (user_email) in Bezug auf "id" in die bestehende Tabelle "usermeta u" integrieren.
 

Yaslaw

n/a
Moderator
#5
Das hingegen ist ein JOIN
SQL:
SELECT
   u.user_id AS id,
   e.user_email,
    MAX(CASE WHEN u.meta_key = 'first_name' THEN u.meta_value ELSE NULL END) AS 'Vorname',
    MAX(CASE WHEN u.meta_key = 'last_name' THEN u.meta_value ELSE NULL END) AS 'Nachname',
    MAX(CASE WHEN u.meta_key = 'plz_search' THEN u.meta_value ELSE NULL END) AS 'PLZ',
    MAX(CASE WHEN u.meta_key = 'member_ort' THEN u.meta_value ELSE NULL END) AS 'Ort'  
FROM
   usermeta u
   LEFT JOIN tabelle_mit_mails e
   ON u.user_id = e.user_id
GROUP BY
   i.user_id,
   e.user_email
 
#6
Prima, tausend Dank! Das hat wunderbar hingehauen. Allerdings habe ich die Gruppierung der Mails weggelassen, aber das funktioniert so. ;-)

SQL:
SELECT
    u.user_id AS 'id',
    e.user_email AS 'Mail',
    MAX(CASE WHEN u.meta_key = 'first_name' THEN u.meta_value ELSE NULL END) AS 'Vorname',
    MAX(CASE WHEN u.meta_key = 'last_name' THEN u.meta_value ELSE NULL END) AS 'Nachname',
    MAX(CASE WHEN u.meta_key = 'plz_search' THEN u.meta_value ELSE NULL END) AS 'PLZ',
    MAX(CASE WHEN u.meta_key = 'member_ort' THEN u.meta_value ELSE NULL END) AS 'Ort'
FROM
    usermeta u
LEFT JOIN
    users e
ON
    u.user_id = e.ID
GROUP BY
    u.user_id
 

Yaslaw

n/a
Moderator
#7
Schlecht.
MySQL ist zu brav und gruppiert Felder selber, wenn sie nicht spezifisch aufgelistet sind.
Es ist aber unsauber und wir dir so in keiner anderen Datenbank funktionieren.
Ich rate dir also davon ab.