Mehrere Joins / mehrere Zeilen trotz fehlender Nebendaten

Blue Effect

Mitglied
Hallo!

Ich habe im Anhang ein auf das Problem reduziertes Datenbankmodell mit wenigen Tabellenzeilen eingefügt.

Folgende Abfrage klappt bereits und fragt eine Spielansetzung mit ihren Teams, Quoten und Sportart ab:
Code:
SELECT wetten_wetten.*, wetten_wetten.id AS wettID, wetten_quoten.id AS quotenID, wetten_quoten.position, wetten_quoten.quote, wetten_sportarten.id AS sportartID, wetten_sportarten.titel AS sportartTitel, wetten_kategorien.id AS ligaID, wetten_kategorien.titel AS ligaTitel, wetten_kategorien.land, wetten_eigenewetten.id AS eigeneWettenID FROM (wetten_wetten, wetten_quoten, wetten_sportarten, wetten_kategorien) 
LEFT JOIN wetten_eigenewetten ON wetten_eigenewetten.user=1 AND wetten_eigenewetten.quote=wetten_quoten.id 
WHERE wetten_wetten.id=357758 AND wetten_quoten.wette = wetten_wetten.id AND wetten_sportarten.id = wetten_wetten.sportart AND wetten_kategorien.id = wetten_wetten.kategorie

Jetzt möchte ich die Teamnamen in diesen Query aufnehmen. Ich weiß nur nicht wie. Wenn ich eine weitere LEFT-JOIN-Zeile einfüge gibt es eine Fehlermeldung - abgesehen davon weiß ich nicht ob es der richtige Weg ist.
Wenn ich die Kriterien einfach an die anderen hänge, erscheinen nur zwei Zeilen, da es nur zwei Teams, aber drei Quoten gibt (eine ist für das Unentschieden).

Und ich bin auch dankbar für jeden Tipp zu dieser Struktur. Die Spalte Sport taucht sowohl in wetten_wetten, als auch wetten_kategorien auf, das werde ich mit der Zeit beheben (wegen laufendem Betrieb möchte ich noch erstere Spalte abfragen und dann irgendwann 'umspeichern'). Aber sonst so?
 

Anhänge

Schritt 1 Zur Problemlösungssuche: Den SQL-Code in lesbare Form bringen
SQL:
SELECT 
	wetten_wetten.*, 
	wetten_wetten.id AS wettID, 
	wetten_quoten.id AS quotenID, 
	wetten_quoten.position, 
	wetten_quoten.quote, 
	wetten_sportarten.id AS sportartID, 
	wetten_sportarten.titel AS sportartTitel, 
	wetten_kategorien.id AS ligaID, 
	wetten_kategorien.titel AS ligaTitel, 
	wetten_kategorien.land, 
	wetten_eigenewetten.id AS eigeneWettenID 
FROM 
	(
		wetten_wetten, 
		wetten_quoten, 
		wetten_sportarten, 
		wetten_kategorien
	) 
	LEFT JOIN wetten_eigenewetten 
		ON wetten_eigenewetten.user=1 
		AND wetten_eigenewetten.quote=wetten_quoten.id 
WHERE 
	wetten_wetten.id=357758 
	AND wetten_quoten.wette = wetten_wetten.id 
	AND wetten_sportarten.id = wetten_wetten.sportart 
	AND wetten_kategorien.id = wetten_wetten.kategorie

Zweitens. Wenn du mit JOIN s arbeitest, solltest du alles mit Joins machen
SQL:
...
FROM 
	wetten_wetten
	INNER JOIN wetten_quoten
		ON wetten_quoten.wette = wetten_wetten.id
	INNER JOIN wetten_sportarten
		ON wetten_sportarten.id = wetten_wetten.sportart
	INNER JOIN wetten_kategorien
		ON wetten_kategorien.id = wetten_wetten.kategorie 
	LEFT JOIN wetten_eigenewetten 
		ON wetten_eigenewetten.quote=wetten_quoten.id 
		AND wetten_eigenewetten.user=1
WHERE 
	wetten_wetten.id=357758

Als nächstes empfiehlt es sich, mit Tabellelaliase zu arbeiten. Es macht das ganze lesbarer. Man sieht bei deinem SQL ansonsten vor lauter 'wetten' die Wetten nicht mehr
SQL:
SELECT 
	wetten.*, 
	wetten.id AS wettID, 
	quoten.id AS quotenuotenID, 
	quoten.position, 
	quoten.quote, 
	sportarten.id AS sportartID, 
	sportarten.titel AS sportartTitel, 
	kat.id AS ligaID, 
	kat.titel AS ligaTitel, 
	kat.land, 
	eigen.id AS eigeneWettenID 
FROM 
	wetten_wetten AS wetten
	INNER JOIN wetten_quoten AS quoten
		ON quoten.wette = wetten.id
	INNER JOIN wetten_sportarten AS sportarten
		ON sportarten.id = wetten.sportart
	INNER JOIN wetten_kategorien AS kat
		ON kat.id = wetten.kategorie 
	LEFT JOIN wetten_eigenewetten  AS eigen
		ON eigen.quote=quoten.id 
		AND eigen.user=1
WHERE 
	wetten.id=357758

So, jetzt ist mal das bestehende sauber und lesbar. Und dann lässt sich das team über wetten_wetten_team ganz einfach anbinden
SQL:
SELECT 
	wetten.*, 
	wetten.id AS wettID, 
	quoten.id AS quotenuotenID, 
	quoten.position, 
	quoten.quote, 
	sportarten.id AS sportartID, 
	sportarten.titel AS sportartTitel, 
	kat.id AS ligaID, 
	kat.titel AS ligaTitel, 
	kat.land, 
	eigen.id AS eigeneWettenID,
	-- Teaminformationen
	wteams.team AS team_id,
	teams.teamname
FROM 
	wetten_wetten AS wetten
	INNER JOIN wetten_quoten AS quoten
		ON quoten.wette = wetten.id
	INNER JOIN wetten_sportarten AS sportarten
		ON sportarten.id = wetten.sportart
	INNER JOIN wetten_kategorien AS kat
		ON kat.id = wetten.kategorie 
	LEFT JOIN wetten_eigenewetten  AS eigen
		ON eigen.quote=quoten.id 
		AND eigen.user=1
	-- Die Teams der Wette zuordnen
	LEFT JOIN wetten_wetten_teams AS wteams
		ON wteams.wette = wetten.id
		AND wteams.position = quoten.position
	-- Die Temanamen verknüpfen
	LEFT JOIN wetten_teams AS teams
		ON teams.id = wteams.team
		AND teams.sportart = wetten.sportart
WHERE 
	wetten.id=357758
 
Zuletzt bearbeitet von einem Moderator:
Achja, wenn du es ganz sauber haben willst, dann solltest du das genauer ansehen
SQL:
    LEFT JOIN wetten_eigenewetten  AS eigen
        ON eigen.quote=quoten.id 
        AND eigen.user=1
'user=1' gehört eigentlich nicht in den ON-Teil sondern in ein WHERE-Teil. Wenn du damit aber die Menge der Daten dieser einen tabelle reduzieren möchtest, solltest du es in eine Unterabfrage setzen
SQL:
    LEFT JOIN (SELECT * FROM wetten_eigenewetten WHERE user=1) AS eigen
        ON eigen.quote=quoten.id
 
Zuletzt bearbeitet von einem Moderator:
Prima!

Nun noch eine Frage hierzu:
SQL:
    INNER JOIN wetten_quoten AS quoten
        ON quoten.wette = wetten.id
Wenn in wetten_quoten keine Zeilen für diese Wette vorhanden sind, möchte ich trotzdem die Teamnamen auslesen. Ich habe z.B. das INNER JOIN in dem Teil deshalb gegen ein LEFT JOIN ersetzt. Jetzt kommt immerhin eine Zeile, dort ist teamname aber NULL.
Muss ich den ganzen Query etwas umändern?
 
Zuletzt bearbeitet von einem Moderator:
Das problem ist, dass das Team im obigen SQL über die Quoten verknüpft ist.
SQL:
    LEFT JOIN wetten_wetten_teams AS wteams
        ON wteams.wette = wetten.id
        AND wteams.position = quoten.position
Wenn nun bei quoten NULL ist, gibts logischerweise kein Team dazu.
Da ich kein DB-Diagramm haber sondern nur die Tabellen hatte ich die Verküpfung oben so gmacht. Ev. hast du ja aber auch eine andere Beziehung wie du an ein Team kommst.
Es lohnt sich bei sovielen Tabellen mal ein Diagramm aufzuzeichnen
 
Zuletzt bearbeitet von einem Moderator:
Das problem ist, dass das Team im obigen SQL über die Quoten verknüpft ist.
SQL:
    LEFT JOIN wetten_wetten_teams AS wteams
        ON wteams.wette = wetten.id
        AND wteams.position = quoten.position
In dem Fall soll nur wteams.position gelesen werden. Ein Vergleich mit quoten.position ist nicht nur unmöglich wie du schreibst, sondern auch gar nicht nötig.

Ein Diagramm werde ich mir für diese Struktur bald anfertigen. :)
 
Zuletzt bearbeitet von einem Moderator:
Dann komm wieder wenn du das hast. Ansonsten musst du selber herausfinden über welchen Weg du das Team einbinden kannst
 
Prima!

Nun noch eine Frage hierzu:
SQL:
    INNER JOIN wetten_quoten AS quoten
        ON quoten.wette = wetten.id
Wenn in wetten_quoten keine Zeilen für diese Wette vorhanden sind, möchte ich trotzdem die Teamnamen auslesen.
Ich habe diesen Teil nun gegen ein LEFT JOIN ersetzt und 'AND wteams.position = quoten.position' beim LEFT JOIN wetten_wetten_teams entfernt:
SQL:
SELECT 
    wetten.*, 
    wetten.id AS wettID, 
    quoten.id AS quotenuotenID, 
    quoten.position, 
    quoten.quote, 
    sportarten.id AS sportartID, 
    sportarten.titel AS sportartTitel, 
    kat.id AS ligaID, 
    kat.titel AS ligaTitel, 
    kat.land, 
    eigen.id AS eigeneWettenID,
    -- Teaminformationen
    wteams.team AS team_id,
    teams.teamname
FROM 
    wetten_wetten AS wetten
    INNER JOIN wetten_quoten AS quoten
        ON quoten.wette = wetten.id
    INNER JOIN wetten_sportarten AS sportarten
        ON sportarten.id = wetten.sportart
    INNER JOIN wetten_kategorien AS kat
        ON kat.id = wetten.kategorie 
    LEFT JOIN wetten_eigenewetten  AS eigen
        ON eigen.quote=quoten.id 
        AND eigen.user=1
    -- Die Teams der Wette zuordnen
    LEFT JOIN wetten_wetten_teams AS wteams
        ON wteams.wette = wetten.id
        AND wteams.position = quoten.position
    -- Die Temanamen verknüpfen
    LEFT JOIN wetten_teams AS teams
        ON teams.id = wteams.team
        AND teams.sportart = wetten.sportart
WHERE 
    wetten.id=357758
(Der Vorschlag aus Beitrag 4 ist hier noch nicht eingearbeitet.)
Wenn keine Quoten vorhanden sind, dann klappt das auch sehr gut. Da ich aber vorher nicht weiß, ob es Quoten gibt, kann ich diese Bedingung nicht einfach rausnehmen, da ja sonst die Teams nicht zur Quote gehören. Kann man die Bedingung auf optional setzen?
 
Zuletzt bearbeitet von einem Moderator:
Zurück