Hallo Marc,
MySQL kann doch Left/Right Joins, oder? Genauso wie Ilja erscheint mir
die Lösung deines Problems mittels eines Joins zu banal, zu einfach.
Mir auch, außer dass Du einen JOIN benötigst :-)
OK, ich habe mich vielleicht nicht gut genug ausgedrückt. Ich möchte am Ende ein Resultat wie dieses hier haben:
song_id | songname | songurl | artist_id | artistname | artisturl
0 | Was Zählt | http://dietotenhosen.de/waszaehlt.mp3 | 0 | Die Toten Hosen | http://dietotenhosen.de/
1 | Der Graf | http://bademeister.com/dergraf.ogg | 1 | Die Ärzte | http://bademeister.com/
2 | Fliegen | http://dietotenhosen.de/fliegen.mp3 | 0 | Die Toten Hosen | http://dietotenhosen.de/
Dazu benötigst Du einen INNER JOIN :-)
Die SQL-Abfrage für das Ding ist an sich ja auch nicht so schwer, bis auf mein kleines Problem.
Erst mal die SQL-Abfrage:
SELECT songs.id AS song_id, songs.name AS songname, songs.url AS songurl, songs.artist_id AS artist_id, (...) AS artistname, (...) AS artisturl ORDER BY artistname LIMIT 49,99;
1. Lass einmal LIMIT aussen vor :-)
Das kommt später
2. Überschriften umschreiben ist ebenfalls für den Grundansatz überflüssig.
Das kommt später
3. Was Du derzeit hast, ist ein CROSS JOIN, das Kreuzprodukt der beiden
Mengen.
An diesem Konstrukt wird wohl eher deutlich was ich erreichen möchte. Ich weiß nur nicht, was ich bei den Punkten einsetzen soll - der artistname und die artisturl sollen in Abhängigkeit von artist_id ermittelt werden.
Aus Deinem SQL-Code auf keinen Fall. Das ist nicht das, was Du willst!
Du willst den INNER JOIN.
Als Beispiel lasse ich jetzt mal nach dem artistname sortieren, das Ganze soll natürlich beliebig nach anderen Spaltennamen (bsp. nach der Zeit des Eintrags oder nach dem Songnamen) sortiert werden können.
Kein Problem, die Lösung heißt (INNER) JOIN.
Hoffentlich gibt es für dieses Problem eine einfache Lösung... :-)
Ja, die heißt INNER JOIN.
Vielleicht hast du Recht und JOIN ist das was ich brauche, aber aus der Dokumentation werde ich mangels guter Erklärung einfach nicht schlau. :-(
Was macht JOIN denn genau?
Ein Join ist eine Verknüpfung zweier Tabellen. Das Ergebnis der Verknüpfung ist eine weitere Tabelle:
Join: A × B -> C
Ganz einfach:
Aus der Join-Bedingung leitet sich die Art des Joins ab:
Wenn Du keine JOIN-Bedingung angibst, dann erhälst Du als Ergebnismenge das Kreuzprodukt der beiden Ausgangsmengen (auch CROSS JOIN genannt und selten gewünscht.
Tabelle A Tabelle B
id | Wert id | Wert
--------- ---------
1 | A 1 | Marc
2 | B 2 | Ilja
3 | C 2 | Frank
4 | D
Den Cross-Join erhältst Du mit
SELECT A.id, A.Wert, B.id, B.Wert FROM A, B
A.id A.Wert B.id B.wert
-----------------------
1 A 1 Marc
1 A 2 Ilja
1 A 2 Frank
2 B 1 Marc
2 B 2 Ilja
2 B 2 Frank
3 C 1 Marc
3 C 2 Ilja
3 C 2 Frank
4 D 1 Marc
4 D 2 Ilja
4 D 2 Frank
Dies ist in den seltensten Fällen gewünscht. Die Anzahl der Zeilen ist Anzahl Zeilen in A mal Anzahl Zeilen in B. Die Abfrage kann eventuell _sehr_ viel Zeit in Anspruch nehmen :-)
Möchtest Du nur die Datensätze, bei denen die Werte in den id-Feldern übereinstimmen, so erhältst Du den NATURAL JOIN (normalerweise alle Spalten beider Tabellen). Dies kannst Du je nach SQL-Dialekt über verschiedene Syntax erreichen:
SELECT
A.id,
A.Wert,
B.id,
B.Wert
FROM A
INNER JOIN B
ON A.id = B.id /* Join-Bedingung */
oder
SELECT
A.id,
A.Wert,
B.id,
B.Wert
FROM A
INNER JOIN B USING (id) /* Join-Bedingung */
oder einfach als WHERE-Klausel (was mir persönlich widerstrebt)
SELECT
A.id,
A.Wert,
B.id,
B.Wert
FROM A, B
WHERE A.id = B.id
Ergebnis:
A.id A.Wert B.id B.wert
-----------------------
1 A 1 Marc
2 B 2 Ilja
2 B 2 Frank
Soll nun die Spalte der JOIN-Bedingung nur einmal angezeigt werden, so haben wir den INNER JOIN, Beispiel:
SELECT
A.id,
A.Wert,
B.Wert
FROM A
INNER JOIN B
ON A.id = B.id /* Join-Bedingung */
Ergebnis:
A.id A.Wert B.wert
-----------------------
1 A Marc
2 B Ilja
2 B Frank
Ob Du in diesem Fall die Spalte aus A oder B nimmst, spielt keine Rolle.
Theta-Join:
Ist die Bedingung keine Gleichheitsbeziehung, sondern z.B. eine "Kleiner als" oder "Größer als"-Relation, so spricht man von einem Theta-Join.
LEFT (OUTER) JOIN:
Möchtest Du _alle_ Datensätze aus A, auch wenn in B kein passender Detaildatensatz vorhanden ist, so verwendest Du den LEFT OUTER JOIN:
In den entsprechenden Spalten, die aus Tabelle B stammen, steht dann in der Ergebnistabelle der NULL-Wert (nicht die Zeichenfolge "NULL", nicht die Zahl 0).
SELECT
A.id,
A.Wert,
B.id,
B.Wert
FROM A
LEFT OUTER JOIN B
ON A.id = B.id /* Join-Bedingung */
Ergebnis:
Ergebnis:
A.id A.Wert B.id B.wert
-----------------------
1 A 1 Marc
2 B 2 Ilja
2 B 2 Frank
3 C NULL NULL
4 D NULL NULL
Zu den Join-Spalten: Diese müssen _nicht_ den gleichen Namen tragen (außer Du willst USING verwenden), viele DBMS verlangen jedoch, dass sie von gleichem Datentyp und gleicher Grösse sind. Dazu konsultiere das Handbuch Deines DBMS.
Freundliche Grüße
Vinzenz