MySQL Join schnall ich nicht :(

bossi

Erfahrenes Mitglied
Hallo ihr Profis,
ich schnall das mit diesen MySQL JOIN einfach nicht.
Ich habe 3 tabellen:
t1 mit spalten t1id & inhalt
t2 mit spalten t2id & t3id


Nun möchte ich via index.php?id=1&t3id=2 den Inhalt aus t1 haben, aber es darf in t2 nicht t2id=1 & t3id=2 sein.

Habe es wie folgt versucht, allerdings kommt nichts zurück :(
PHP:
$datensatz = db_query("SELECT *
FROM  t1
INNER JOIN t2 ON (t2.t2id=t1.id AND t2.t3id!=".$_GET['t3id'].")
WHERE t1.id=".$_GET['id']."");

Gruß
Bossi
 
Moin Bossi,

vom eventuell "falschen" Ergebnis mal kurz abgesehen:
in einer INNER JOIN-Verknüpfung solltest Du eigentlich immer nur Primary Keys mit Foreignkeys, also zwei jeweils im Index enthaltene Felder ansprechen.
Und selbst wenn auf dem t3id-Feld ein Index läge, wären die Optimizer-Möglichkeiten bei einer "WHERE t3id ungleich.."-Verknüpfung eher schnell abzählbar.

Besser so:
Code:
SELECT t1.* 
FROM  t1, t2
WHERE t1.id=t2.id
AND t1.id = DeineT1Id
AND t2.t3id != DeineT3id;
Zum tatsächlichen Code - t1.id, t2.id und t2.t3id sind in Deinem Modell auch alle numerisch?

Grüße
Biber
 
Jo danke Dir.
Und wpfür sollte man das LEFT JOIN nutzen bzw. wann sollte man sowas nutzen statt eine schleife ?
 
Wenn du mit Schleife ne Schleife in ner Programmiersprache meinst wo du das Ergebnis der ersten Abfrage durchläufst und für jeden Datensatz den entsprechenden Datensatz in der anderen Tabelle mit einer eigenen Abfrage suchst:
Du solltest einen JOIN immer einer Schleife vorziehen. Eine solche Schleife ist als n+1 Select Problem bekannt und der schlimmste Performance-Fresser den du programmieren kannst.

n+1 deswegen weil du einen Select für die Hauptabfrage brauchst, die dir dann n Datensätze zurückliefert. Für jeden dieser Datensätze brauchst du wiederum einen Select: macht ergo n+1 selects. Das stellen einer Abfrage an eine Datenbank ist im Vergleich zu ein wenig PHP Code ewig langsam. Deshalb sollte die anzahl der Datenbankabfragen weitestgehenst minimiert werden. Lieber eine komplexe Abfrage als 3 einfache.
 
Zuletzt bearbeitet:
Also das hier kann nicht gehen wen in tabelle2 mehr Dtaensätzen sind.
Code:
SELECT t1.* 
FROM  t1, t2
WHERE t1.id=t2.id
AND t1.id = DeineT1Id
AND t2.t3id != DeineT3id;
Deshal brauche ich was in der art einer Schleife, die die Daten aus tablle1 ausgibt wen es in tabelle2 kein Datensatz gibt.

Beipsiel: Aus tabelle1 will ich die Daten mit der ID 1000 haben.
In tabelle2 mit Spalten id1 und id2 sind folgende Datensätze vorhanden:
Datensatz1: id1=1000 id2=1234
Datensatz2: id1=1000 id2=4321

Nun möchte ich tabelle1 abfragen un gleichzeitig mit tabelle2 vergleichen.
Sollte in tablle2 id1=1000 id2=1234 vorhanden sein, dann nichts ausgeben.
Sowas muss man doch mit einer Join lösen, wen man keine lästige Schleife benutzen will oder ?


Habe sowa in ein anderen Code gesehen:
PHP:
$kamp = db_query ("SELECT t1.* 
FROM xxx t1 
LEFT JOIN yyy t2 
ON (t1.tan=t2.tan AND (t2.ip='".$ip."') AND t2.bis > ".time().") 
WHERE t1.tan = '".$_GET['tan']."' AND t2.tan IS NULL AND t1.werbeart='autosurf' AND t1.menge>=1 AND t1.status=1 AND t1.sponsor!=".$_SESSION['uid']." LIMIT 1");
In Tabelle xxx & yyy sind sehr viele Datensätzen.
Es wird nur ein Datensatz aus Tabelle xxx ausgegeben wen alles in Tabelle yyy NICHT zutrifft.
 
Zuletzt bearbeitet:
Ich habe das Problem leider nicht verstanden.

Wenn du sowas machen willst wie: Gebe alle Datensätze von t1 aus für die kein Datensatz in t2 vorhanden ist mit t2.id2=1234 könntest du das auch so machen:

SELECT * from tabelle1 t1 WHERE NOT EXISTS(SELECT * FROM tabelle2 t2 WHERE t2.id1=t1.id1 AND t2.id2=1234)

Dann erhältst du alle Datensätze von t1 für die entweder kein Datensatz in t2 vorhanden. Sind ein oder mehrere Datensätze für t1 vorhanden dann darf davon keine den Wert 1234 für id2 besitzen.
 
Und wieso mach andere das via JOIN, wie in mein Beispiel das ich gefunden habe ?
PHP:
$kamp = db_query ("SELECT t1.* 
FROM xxx t1 
LEFT JOIN yyy t2 
ON (t1.tan=t2.tan AND (t2.ip='".$ip."') AND t2.bis > ".time().") 
WHERE t1.tan = '".$_GET['tan']."' AND t2.tan IS NULL AND t1.werbeart='autosurf' AND t1.menge>=1 AND t1.status=1 AND t1.sponsor!=".$_SESSION['uid']." LIMIT 1");
 
Hi,

ein JOIN, bzw. INNER JOIN liefert Dir alle Datensätze aus Tabelle 1, die einen dazugehörigen Datensatz in Tabelle 2 haben.
Ein LEFT JOIN liefert Dir erstmal alle gewählten Datensätze aus Tabelle 1, auch wenn es keinen dazugehörigen Datensatz in Tabelle 2 gibt. Die Felder aus Tabelle 2 sind in diesem Fall dann NULL. Diesen Umstand kannst Du Dir zunutze machen, wenn Du nur die Datensätze aus Tabelle 1 haben willst, die keine Entsprechung in Tabelle 2 haben, indem Du den JOIN darauf einschränkst:

Code:
SELECT t1.* FROM t1
   LEFT JOIN t2
   ON (<deine ON-Bedingungen> AND t2.t2id IS NULL)

LG
 
Also gleich platz mir der Schädel :suspekt:
Wie soll ich da meine Bedingung einbringen *kopf raucht*
Code:
SELECT t1.* FROM t1
   LEFT JOIN t2
   ON (<deine ON-Bedingungen> AND t2.t2id IS NULL)
Auf was bezieht sich t2.t2id IS NULL :confused:
Und meine Bedingungen ist ja:
Beipsiel: Aus tabelle1 will ich die Daten mit der ID 1000 haben.
In tabelle2 mit Spalten id1 und id2 sind folgende Datensätze vorhanden:
Datensatz1: id1=1000 id2=1234
Datensatz2: id1=1000 id2=4321

Nun möchte ich tabelle1 abfragen un gleichzeitig mit tabelle2 vergleichen.
Sollte in tablle2 id1=1000 id2=1234 vorhanden sein, dann nichts ausgeben.
 
Hi,

vielleicht solltest Du erstmal vernünftig beschreiben, worüber Deinen Tabellen denn überhaupt verknüpft sind. Ich hatte aufgrund Deines geposteten SQL-Statements angenommen, dass t2id der Fremdschlüssel aus t1 ist, auch wenn ich den Spaltennamen dann unglücklich finde...

Auf was bezieht sich t2.t2id IS NULL

Das wäre dann besagte Einschränkung. Bitte lies meine Antwort noch mal.

Nun möchte ich tabelle1 abfragen un gleichzeitig mit tabelle2 vergleichen.
Sollte in tablle2 id1=1000 id2=1234 vorhanden sein, dann nichts ausgeben.

Und was ist mit dem 2. Datensatz? Der ja auch id1=1000 hat? Du musst Dein Ziel schon genauer formulieren.

LG
 

Neue Beiträge

Zurück