Mysql left join problem
ScaraX
- datenbank
0 Cheatah0 Vinzenz Mai0 ScaraX0 Vinzenz Mai0 ScaraX3 Vinzenz Mai
Hi,
also, ich habe 2 Tabellen Liga (ID, name) und Clan_liga (ID, ligaID, clanID)
jetzt möchte ich für einen bestimmten Clan alle Ligen angezeigt bekommen und dazu ein hinweis, ob dieser CLan bereits bei der Liga registriert ist oder nicht
mein bisheriger Ansatz:
SELECT
liga.ID,
liga.name,
clan_liga.clanID,
(clan_liga.ID > 0) as isregistered
FROM
liga left join clan_liga on liga.ID = clan_liga.ligaID
WHERE
clan_liga.clanID = [hier clanID einsetzen]
GROUP BY
liga.ID
ORDER BY
liga.name ASC
damit bekomme ich leider nur die Ligen angezeigt, bei denen der Clan registriert ist, jedoch nicht die anderen...
habs auch schon mit
WHERE
clan_liga.clanID = [hier clanID einsetzen]
or
clan_liga.clanID IS NULL
probiert,
aber da bekommt ich dann nur die ligen, an denen clan 3 registriert ist und die ligen, an denen überhaupt kein clan registriert ist, nicht aber die, an denen nur andere clans (außer clan 3) registriert sind... auch nit das was ich wollte...
ich hätte gerne ein Ergebnis wie folgendes (bei gewähltem clan 3:
ID name clanID isregistered
1 ligaA null 0
2 ligaB 3 1
3 ligaC 3 1
4 ligaD null 0
5 ligaE null 0
ich hoffe jemand kann mir weiterhelfen!
MfG
ScaraX.
Hi,
damit bekomme ich leider nur die Ligen angezeigt, bei denen der Clan registriert ist, jedoch nicht die anderen...
ah. Du benötigst einen OUTER JOIN.
Cheatah
Hi,
damit bekomme ich leider nur die Ligen angezeigt, bei denen der Clan registriert ist, jedoch nicht die anderen...
ah. Du benötigst einen OUTER JOIN.
soweit ich weiss gibts das bei mysql aber nicht.. bzw. ein LEFT OUTER JOIN funktioniert genau wie LEFT JOIN... habs damit schon probiert, gibt aber das selbe ergebnis...
Cheatah
Hi,
ah. Du benötigst einen OUTER JOIN.
soweit ich weiss gibts das bei mysql aber nicht..
dann glaube daran, dass es das gibt. Manchmal ist der Glaube stärker als jedes Wissen.
bzw. ein LEFT OUTER JOIN funktioniert genau wie LEFT JOIN... habs damit schon probiert, gibt aber das selbe ergebnis...
Dann benötigst Du vielleicht einen RIGHT OUTER JOIN? Zeilen, zu denen bei einer gejointen Tabelle kein Datensatz existiert, werden bei einem OUTER JOIN ins Resultset übernommen, bei einem INNER JOIN nicht.
Cheatah
Grundlage für Zitat #1033.
Hallo
also, ich habe 2 Tabellen Liga (ID, name) und Clan_liga (ID, ligaID, clanID)
jetzt möchte ich für einen bestimmten Clan alle Ligen angezeigt bekommen und dazu ein hinweis, ob dieser CLan bereits bei der Liga registriert ist oder nicht
mein bisheriger Ansatz:
SELECT
liga.ID,
liga.name,
clan_liga.clanID,
(clan_liga.ID > 0) as isregistered
FROM
liga left join clan_liga on liga.ID = clan_liga.ligaID
WHERE
clan_liga.clanID = [hier clanID einsetzen]
GROUP BY
liga.ID
ORDER BY
liga.name ASC
ist eine typische MySQL-Schrott-Anweisung, die jedes andere Datenbankmanagementsystem richtigerweise als syntaktisch falsch zurückweist.
Du musst nach _allen_ Spalten gruppieren, auf die Du _keine_ Aggregatsfunktion anwendest. Du wendest keine Aggregatsfunktion an, also musst Du nach allen Spalten gruppieren. Noch viel einfacher ist es, die überflüssige GROUP-BY-Klausel einfach zu entfernen.
ID name clanID isregistered
1 ligaA null 0
2 ligaB 3 1
3 ligaC 3 1
4 ligaD null 0
5 ligaE null 0ich hoffe jemand kann mir weiterhelfen!
Deine WHERE-Klausel macht Dir alles kaputt. Du möchtest Werte der "linken" Tabelle zugreifen, die NULL-Werte zurückliefern kann. Verschiebe die WHERE-Klausel daher in die JOIN-Bedingung.
Weiterhin halte ich es für möglich, dass Du die COALESCE-Funktion in Deiner berechneten Spalte "isregistered" verwenden möchtest.
Freundliche Grüße
Vinzenz
Hi,
das hilft mir leider nicht weiter...
wenn ich das group by weglasse bekomme ich viel zu viele Ergebniszeilen...
und mit der Where-Klausel muss ich ja irgendwie eingrenzen bzw irgendwo muss ja erwähnt werden, dass es sich um einen bestimmte Clan handelt...
der Wert isregistered soll einfach nur anzeigen, ob ein Clan registriert ist oder nicht... also 0 oder 1
MfG
ScaraX
Hallo
das hilft mir leider nicht weiter...
hast Du es versucht?
wenn ich das group by weglasse bekomme ich viel zu viele Ergebniszeilen...
Nein, wieso? Kann ein Clan mehrfach in der gleichen Liga sein? Wohl kaum.
und mit der Where-Klausel muss ich ja irgendwie eingrenzen bzw irgendwo muss ja erwähnt werden, dass es sich um einen bestimmte Clan handelt...
Ja, nur nicht in der WHERE-Klausel, sondern in der Join-Bedingung.
der Wert isregistered soll einfach nur anzeigen, ob ein Clan registriert ist oder nicht... also 0 oder 1
eben deswegen benötigst Du COALESCE ...
Gib mir zu jeder Liga
- die id
- den Liganamen
- meinen gewünschten Clan, falls er drin ist, sonst NULL
- und ob er registriert ist (als 0 oder 1, aber nicht als NULL)
aufwärts sortiert nach Liganamen
Ich sehe keinen Grund für GROUP BY.
Freundliche Grüße
Vinzenz
Super, danke!
Habs jetzt folgendermaßen gelößt:
SELECT
liga.ID,
liga.name,
clan_liga.clanID,
COALESCE(clan_liga.ID) IS NOT NULL as isregistered
FROM
liga left join clan_liga on liga.ID = clan_liga.ligaID and clan_liga.clanID = [clanID]
ORDER BY
qcms_liga.name ASC
funktioniert soweit ganz gut!
MfG
ScaraX
Hallo
wenn ich das group by weglasse bekomme ich viel zu viele Ergebniszeilen...
Nein, wieso? Kann ein Clan mehrfach in der gleichen Liga sein? Wohl kaum.
und mit der Where-Klausel muss ich ja irgendwie eingrenzen bzw irgendwo muss ja erwähnt werden, dass es sich um einen bestimmte Clan handelt...
Ja, nur nicht in der WHERE-Klausel, sondern in der Join-Bedingung.
der Wert isregistered soll einfach nur anzeigen, ob ein Clan registriert ist oder nicht... also 0 oder 1
eben deswegen benötigst Du COALESCE ...
Ein kleines Beispiel:
Tabelle gremien:
id | bezeichnung
----------------
1 | Spiel
2 | SR
3 | Jugend
4 | Ausbildung
Tabelle mitglieder
id | id_gremium | id_person
-----------------------------
1 | 1 | 10
2 | 1 | 7
3 | 1 | 15
4 | 2 | 1
5 | 2 | 8
6 | 3 | 10
7 | 3 | 5
8 | 4 | 11
9 | 4 | 7
Du möchtest nun alle Gremien anzeigen - und ob die Person mit der id 10 diesem Gremium angehört.
SELECT
g.id,
g.bezeichnung,
m.id_person
FROM
gremien g
LEFT JOIN
mitglieder m
ON
g.id = m.id_gremium
WHERE
m.id_gremium = 10
liefert wegen der speziellen Behandlung von NULL-Werten bei Vergleichen nur folgende Datensätze zurück, die Gremien, denen die Person mit der id 10 angehört:
id | bezeichnung | id_person
----------------------------
1 | Spiel | 10
3 | Jugend | 10
Führst Du jedoch die Einschränkung auf die Person mit der id 10 in der Join-Bedingung auf, so erhältst Du alle Gremien:
SELECT
g.id,
g.bezeichnung,
m.id_person
FROM
gremien g
LEFT JOIN
mitglieder m
ON
g.id = m.id_gremium
AND
m.id_gremium = 10
id | bezeichnung | id_person
----------------------------
1 | Spiel | 10
2 | SR | NULL
3 | Jugend | 10
4 | Ausbildung | NULL
Da jede Person einem Gremium maximal einmal angehören kann und wir auf eine bestimmte Person prüfen, wird jedes Gremium auch genau einmal aufgeführt, kein Anlass, das Schlüsselwort DISTINCT oder grausamerweise sogar eine GROUP-BY-Klausel einzubauen.
Nehmen wir nun noch eine berechnete Spalte mit, die istmitglied heißt:
SELECT
g.id,
g.bezeichnung,
m.id_person,
(m.id > 0) AS istmitglied
FROM
gremien g
LEFT JOIN
mitglieder m
ON
g.id = m.id_gremium
AND
m.id_gremium = 10
so erhalten wir aufgrund der besonderen Behandlung bei Vergleichen mit NULL-Werten:
id | bezeichnung | id_person | istmitglied
------------------------------------------
1 | Spiel | 10 | 1
2 | SR | NULL | NULL
3 | Jugend | 10 | 1
4 | Ausbildung | NULL | NULL
das heißt eben _nicht_ die Werte 0 und 1. Die Funktion COALESCE ermöglicht es, 0 statt NULL zu bekommen, denn COALESCE(NULL, 0) ergibt 0, COALESCE(1,0) ergibt jedoch 1:
SELECT
g.id,
g.bezeichnung,
m.id_person,
COALESCE(m.id > 0), 0) AS istmitglied
FROM
gremien g
LEFT JOIN
mitglieder m
ON
g.id = m.id_gremium
AND
m.id_gremium = 10
liefert dagegen:
id | bezeichnung | id_person | istmitglied
------------------------------------------
1 | Spiel | 10 | 1
2 | SR | NULL | 0
3 | Jugend | 10 | 1
4 | Ausbildung | NULL | 0
Wende mein Beispiel auf Dein Problem an ...
Freundliche Grüße
Vinzenz