JOIN falls Verknüpfung vorhanden
Oli
- datenbank
-1 Hans0 Vinzenz Mai0 Oli0 Vinzenz Mai0 Oli
Hallo Leute,
ich komme mit meiner Abfrage nicht weiter:
Ich habe zwei Tabellen User und Bilder
---------------------------
ID User
1 Anna
2 Bernd
3 Chis
---------------------------
Tab Bilder
id_user bild_name sort
1 anna1.jpg 1
1 anna2.jpg 2
2 bernd.jpg 1
---------------------------
SELECT
user.name,
bilder.bild_name
FROM
user,
bilder
WHERE
user.id_user = bilder.id_user
...bekomme ich nur User, die ein Bild haben (ist ein OUTER JOIN oder?)
mache ich das ganze mit LEFT JOIN
LEFT JOIN $bilder ON user.id_user = bilder.id_user
bekomme ich lie Liste der Bilder
---------------------------
Anna anna1.jpg
Anna anna2.jpg
Bernd bernd.jpg
Chris -
---------------------------
ich hätte als Ausgabe jetzt gerne eine Liste aller User und falls sie ein Bild haben das derste Bild (sort=1) dazu
---------------------------
Anna anna1.jpg
Bernd bernd.jpg
Chris -
---------------------------
schön wäre auch eine Variante mit in der ich die Bild, falls mehrere als array zurückbekomme, könnte ich in PHP wieder auseinanderfummeln
---------------------------
Anna anna1.jpg, anna2.jpg
Bernd bernd.jpg
Chris -
---------------------------
Hi !
SELECT
user.name,
bilder.bild_name
FROM
user,
bilder
WHERE
user.id_user = bilder.id_user...bekomme ich nur User, die ein Bild haben (ist ein OUTER JOIN oder?)
mache ich das ganze mit LEFT JOIN
LEFT JOIN $bilder ON user.id_user = bilder.id_userbekomme ich lie Liste der Bilder
Anna anna1.jpg
Anna anna2.jpg
Bernd bernd.jpg
Chris -
...
schön wäre auch eine Variante mit in der ich die Bild, falls mehrere als array zurückbekomme, könnte ich in PHP wieder auseinanderfummeln
Anna anna1.jpg, anna2.jpg
Bernd bernd.jpg
Chris -
Also, Du hast die Elemente als LISTE in Deiner Bank. Somit bekommst Du sie auch als LISTE wieder heraus. Was spricht also dagegen, die LISTE einzulesen und in Deinem PHP-Skript das Array damit aufzubauen ?
Gruß
Hans
hi,
Also, Du hast die Elemente als LISTE in Deiner Bank. Somit bekommst Du sie auch als LISTE wieder heraus. Was spricht also dagegen, die LISTE einzulesen und in Deinem PHP-Skript das Array damit aufzubauen ?
Da spricht natürlich genau so wenig (oder viel?) dagegen, wie dagegen, heutzutage noch durch Aneinanderklopfen von Steinen Feuer machen zu wollen, mit Hammer und Meißel einen Brief "in Stein" zu schreiben, etc.
gruß,
wahsaga
mache ich das ganze mit LEFT JOIN
LEFT JOIN $bilder ON user.id_user = bilder.id_userbekomme ich lie Liste der Bilder
Anna anna1.jpg
Anna anna2.jpg
Bernd bernd.jpg
Chris -
Also, Du hast die Elemente als LISTE in Deiner Bank. Somit bekommst Du sie auch als LISTE wieder heraus. Was spricht also dagegen, die LISTE einzulesen und in Deinem PHP-Skript das Array damit aufzubauen ?
naja ich könnte wohl mit PHP abfragen if ($name_alt != $name_neu) ...
halte ich aber nicht für sinnvoill mir die ganzen Daten aus der DB zu holen und in PHP wieder wegzuwerfen. Ich brauch zu jedem User ja nur das erste Bild, falls vorhanden (und nicht die restlichen 25).
Oli
Hallo Oli,
ID User
1 Anna
2 Bernd
3 Chis
Tab Bilder
id_user bild_name sort1 anna1.jpg 1
1 anna2.jpg 2
2 bernd.jpg 1
> SELECT
> user.name,
> bilder.bild_name
> FROM
> user,
> bilder
> WHERE
> user.id_user = bilder.id_user
arrgh, diese häßlichen impliziten Joins. Da sträuben sich alle noch vorhandenen Haare. Bitte lies
...bekomme ich nur User, die ein Bild haben (ist ein OUTER JOIN oder?)
mache ich das ganze mit LEFT JOIN
LEFT JOIN $bilder ON user.id_user = bilder.id_userbekomme ich lie Liste der Bilder
Anna anna1.jpg
Anna anna2.jpg
Bernd bernd.jpg
Chris -
Ja das ist so, und das ist richtig so.
ich hätte als Ausgabe jetzt gerne eine Liste aller User und falls sie ein Bild haben das derste Bild (sort=1) dazu
Anna anna1.jpg
Bernd bernd.jpg
Chris -
Du suchst die korrelierenden Unterabfragen. Siehe z.B. Rouvens Archivposting. Die meisten Datenbankmanagementsyste (DBMS) kommen mit solchen Abfragen zurecht, das weit verbreitete MySQL jedoch leider erst ab der Version 4.1.
Bitte nenne uns daher Dein DBMS, inklusive Version.
Freundliche Grüße
Vinzenz
Hallo Vinzenz Mai,
ID User
1 Anna
2 Bernd
3 Chis
Tab Bilder
id_user bild_name sort1 anna1.jpg 1
1 anna2.jpg 2
2 bernd.jpg 1
SELECT
user.name,
bilder.bild_name
FROM
user,
bilder
WHERE
user.id_user = bilder.id_user
>
> arrgh, diese häßlichen impliziten Joins. Da sträuben sich alle noch vorhandenen Haare. Bitte lies
>
> [Einführung Joins](http://aktuell.de.selfhtml.org/artikel/review/datenbanken/joins/)
ähmm
~~~sql
SELECT
user.name,
bilder.bild_name
FROM
user,
bilder
INNER JOIN user
ON user.id_user = bilder.id_user
... wäre besser? Sorry wenn ich so blöd frage :-)
...bekomme ich nur User, die ein Bild haben (ist ein OUTER JOIN oder?)
mache ich das ganze mit LEFT JOIN
LEFT JOIN bilder ON user.id_user = bilder.id_user
bekomme ich lie Liste der Bilder
Anna anna1.jpg
Anna anna2.jpg
Bernd bernd.jpg
Chris -
Anna anna1.jpg
Bernd bernd.jpg
Chris -
Bitte nenne uns daher Dein DBMS, inklusive Version.
ja sorry das habe ich vergessen: MySQL 4.1.14
Oli
Hallo Oli,
ID User
1 Anna
2 Bernd
3 Chis
Tab Bilder
id_user bild_name sort1 anna1.jpg 1
1 anna2.jpg 2
2 bernd.jpg 1
[... leider falscher Join ...]
... wäre besser? Sorry wenn ich so blöd frage :-)
wenn es richtig wäre, dann ja.
Anna anna1.jpg
Bernd bernd.jpg
Chris -
ja sorry das habe ich vergessen: MySQL 4.1.14
Ja, da gehen die von mir angesprochenen Subselects.
Du suchst das Minimum der Spalte Sort, ein erster Ansatz wäre somit folgender ungetestes Statement:
SELECT
user.name,
b1.bild_name
FROM
user
-- Da Du zweimal auf die Tabelle bilder zugreifen musst,
-- führen wir einen Aliasnamen ein.
LEFT JOIN bilder b1
ON user.id_user = b1.id_user
-- Nun suchen wir genau das richtige Bild aus, das ist dasjenige
-- mit dem kleinsten Eintrag in der Spalte `sort`
WHERE bilder.sort = (SELECT MIN(sort) FROM bilder b2 WHERE b1.id = b2.id)
Freundliche Grüße
Vinzenz
SELECT
user.name,
b1.bild_name
FROM
user
-- Da Du zweimal auf die Tabelle bilder zugreifen musst,
-- führen wir einen Aliasnamen ein.
LEFT JOIN bilder b1
ON user.id_user = b1.id_user
-- Nun suchen wir genau das richtige Bild aus, das ist dasjenige
-- mit dem kleinsten Eintrag in der Spaltesort
WHERE bilder.sort = (SELECT MIN(sort) FROM bilder b2 WHERE b1.id = b2.id)
>
Hallo Vinzenz
klappt auf die Schnelle nicht, gibt eine SQL Fehlermeldung aber schon mal ein Ansatz.
Vielen Dank
Oli
Hallo Oli,
hier korrigiertes funktionierendes SQL-Statement:
Tab user
ID User
1 Anna
2 Bernd
3 Chis
Tab Bilder
id_user bild_name sort
1 anna1.jpg 1
1 anna2.jpg 2
2 bernd.jpg 1
1. Schritt:
Zeige mir alle User an, dazu die Bildnamen, sofern welche existieren
SELECT
user.user,
b1.bild_name
FROM user
LEFT JOIN bilder b1 -- LEFT JOIN, damit auch die User angezeigt werden,
-- für die kein Bildeintrag existiert
-- b1 ist ein Aliasname für den Tabellennamen bilder
-- Wir greifen später ein zweites Mal auf die Tabelle zu.
ON user.id = b1.id_user -- JOIN-Bedingung
Ergebnis:
user bild_name
-----------------------------------
Anna anna1.jpg
Anna anna2.jpg
Bernd bernd.jpg
Chris NULL
2.Schritt:
Schränke die Ausgabe auf das Bild ein, das in der Spalte sort den kleinsten Wert aufweist.
SELECT
user.user,
b1.bild_name
FROM user
LEFT JOIN bilder b1 -- LEFT JOIN, damit auch die User angezeigt werden,
-- für die kein Bildeintrag existiert
-- b1 ist ein Aliasname für den Tabellennamen bilder
-- Wir greifen später ein zweites Mal auf die Tabelle zu.
ON user.id = b1.id_user -- JOIN-Bedingung
WHERE b1.sort = (
SELECT MIN(b2.sort) -- Nur die Datensätze mit dem kleinsten sort-Wert
FROM bilder b2
WHERE b2.id_user = b1.id_user) -- bei gleichem user (id_user)
Das Ergebnis
user bild_name
-----------------------------------
Anna anna1.jpg
Bernd bernd.jpg
kann noch nicht zufrieden stellen. Zwar wird wie gewünscht bei Anna nur das Bild mit dem kleinsten sort-Wert angezeigt, dafür ist der Eintrag von Chris verlorengegangen. Dies liegt daran, dass für Chris in der Spalte b1.sort der Wert NULL steht. Diesen Datensatz (und vergleichbare) müssen wir gesondert betrachten. Den Vergleich mit NULL-Werten führt man mit IS NULL durch.
Schritt 3:
SELECT
user.user,
b1.bild_name
FROM user
LEFT JOIN bilder b1 -- LEFT JOIN, damit auch die User angezeigt werden,
-- für die kein Bildeintrag existiert
-- b1 ist ein Aliasname für den Tabellennamen bilder
-- Wir greifen später ein zweites Mal auf die Tabelle zu.
ON user.id = b1.id_user -- JOIN-Bedingung
WHERE b1.sort = (
SELECT MIN(b2.sort)
FROM bilder b2
WHERE b2.id_user = b1.id_user)
OR b1.sort IS NULL -- damit auch die User ohne Bild berücksichtigt werden.
liefert das gewünschte Ergebnis
user bild_name
-----------------------------------
Anna anna1.jpg
Bernd bernd.jpg
Chris NULL
Freundliche Grüße
Vinzenz