[mysql] Abfrage über 2 Tabellen

chrisi01

Romy lieb haben
ID: 101113
L
26 November 2008
2.854
238
hi

ich stehe damit jedes mal auf Kriegsfuss und jetzt brauch ich den mist wieder

$abfrage = "SELECT traffic.url, reload.url, reload.ip FROM reload,traffic WHERE reload.ip != '$ip' ORDER BY RAND()";
$ergebnis = mysql_query($abfrage);
while($row = mysql_fetch_object($ergebnis))
{
echo $row->url;
}

Sprich ich hab 2 Tabellen.
tabelle1 = traffic dort eine Spalte URL (restlichen sind unwichtig)
tabelle2 = reload dort eine Spalte ip und eine url (restlichen sind unwichtig)

nun ja ihr seht ja soll ne reloadsperre werden ;) ich will halt ne url haben die in der tabelle reload noch nicht mit der ip vorhanden ist. Ich vermute ja fast das es so gar nicht geht und ich wieder left join brauch wo ich eifnach nicht durchblicke deswegen hab ich mir diese Abfrage oben ergooglet nur leider geht die nicht :( ich bekomme NICHTS zurück. obwohl in tabelle traffic was drinnen ist und reload aktuell komplett leer ist.

mfg

chris
 
Wenn du joinst, brauchst du eine Join-Bedingung. Deine Abfrage liefert erst einmal ein kartesisches Produkt (LEFT JOIN ist nur eine abkürzende Schreibweise, d.h. du kannst, wenn du dieses Konstrukt nicht magst, jede Abfrage ohne dieses machen), was du sicher nicht haben willst.
obwohl in tabelle traffic was drinnen ist und reload aktuell komplett leer ist.
Was ist das Ergebnis eines Produkts, wenn ein Faktor 0 ist? Richtig: Null, d.h. du kriegst auch gar kein Ergebnis im Kreuzprodukt und mit WHERE 0 Datensätze filtern, bleiben immer noch 0 Datensätze übrig.

Im Übrigen: Eine Lösung für dein Problem steht bereits im FAQ-Forum ;)
 
SCH.. eibenkleister.

ich hab doch reingeguckt und das Thema nicht gesehen. SRY von deiner Ausführung versteh ich zwar grad Bahnhof aber ich glaub mit dem ausm FAQ dürfte ich klar kommen ;)

danke dir

mfg

chris
 
SRY vond eienr Ausführung evrsteh ich zwar grad Bahnhof
Dann solltest du mir mal sagen, was genau du daran nicht verstehst.

Ich mein, ohne dass du meinen Post verstehst, wirst du mit Datenbanken wohl nicht weit kommen und es gibt leider auch nicht zu jedem deiner zukünftigen Probleme n FAQ-Thread hier. Du solltest dir die 1-2 Stunden nehmen und das Konzept vom Tabellenverbund verstehen ;) Also, schieß los. Was verstehst du nicht?
 
wenn ich ehrlich bin den ganzen text nicht. kann aber auch gut an der Uhrzeit liegen.

Muss da morgen nochmal drüber nachdenken aber

Code:
$abfrage = "SELECT traffic.url FROM traffic LEFT JOIN reload USING(url)WHERE reload.url IS NULL And reload.ip IS NULL ORDER BY RAND() LIMIT 0,1";

schaut schon mal gut aus. Morgen noch testen ob es klappt wenn eine ip drinnen steht und dann hab ich es schon.

Du solltest dir die 1-2 Stunden nehmen und das Konzept vom Tabellenverbund verstehen

sollte ich vielleicht mal wobei ich sagen muss bisher komm ich immer sehr gut zurecht nur wenn es mal wieder um die Reloadsperre geht dann geht es wieder von vorne los. Sonst hab ich bei keiner Abfrage Probleme.

mfg

Chris
 
hi

also ich hab mir jetzt nochmal gedanken gemacht da das oben nicht geklappt hat (der hat die ip nicht beachtet also sobald irgendwer in der reload war waren es auch alle anderen)

danach kam mir folgende Idee:

Code:
$abfrage = "SELECT traffic.url, traffic.reload FROM traffic LEFT JOIN reload USING(url) WHERE reload.ip != '$ip' ORDER BY RAND() LIMIT 0,1";

die aber auch wieder nicht klappt da er immer alle Datensätze nimmt obwohl meine ip in der reload vorhanden ist.

Code:
SELECT traffic.url, traffic.reload FROM traffic LEFT JOIN reload USING(url) WHERE reload.url IS NULL AND reload.ip != '$ip' ORDER BY RAND() LIMIT 0,1

hab icha uch noch probiert aber da kam wieder das gleiche wie beim ersten raus.

Code:
SELECT traffic.url, traffic.reload FROM traffic LEFT JOIN reload USING(url) WHERE reload.url != traffic.url AND reload.ip != '$ip' ORDER BY RAND() LIMIT 0,1
da dachte ich echt jetzt hab ich den Einfall klappt aber auch nicht...

Irgendwie dreh ich mich im Kreis und komme nicht auf die richtige Idee. Kannst du mir nochmal helfen? Und bitte vermeide das Wort kartesisches Produkt hab mal bei wiki nachgeschlagen und fast nen Lachkrampf bekommen da ich davon nichts verstanden hab :mrgreen: Ich wills ehrlich gesagt auch gar nicht (mehr) wissen.

mfg

chris
 
Versuchs mal nicht mit einem JOIN, sondern mit einer Subquery:

non-correlated subquery:

SELECT traffic.url
FROM traffic
WHERE traffic.url NOT IN (
SELECT reload.url
FROM reload
WHERE reload.ip = '$ip' )

oder correlated subquery:

SELECT traffic.url
FROM traffic
WHERE NOT EXISTS
( SELECT * FROM reload
WHERE reload.url = traffic.url
AND relaod.ip = '$ip' )
 
und da gehts ja so einfach das sogar ich es noch kapier....

Vielen lieben dank das funktioniert 1a und ich verstehe den Sinn dahinter sogar, was ich bei LEFT JOIN immer noch nicht behaupten kann.

mfg

Chris
 
Freut mich, dass ich Dir helfen konnte.

Mit einem LEFT JOIN geht es natürlich auch, aber ich weiss nicht, ob jeder SQL-Dialekt diese Anweisung korrekt verarbeitet:


SELECT traffic.url
FROM traffic LEFT JOIN reload
ON traffic.url = reload.url
AND reload.ip = '$ip'
WHERE reload.ip IS NULL
 
[..]ich sag nur: Nie wieder left join wenn es so viel einfacher und verständlicher geht :)[..]

Ein JOIN ist aber meine ich schneller als 'ne Sub-Query ;)

Dein Problem war, dass MySQL bei deiner Abfrage nicht weiß, woran er deine beiden Tabellen verbinden kann.
Wenn du also bei beiden Tabellen eine Spalte URL hast, dann kannst du die Tabellen z.B. anhand der URL verbinden (mit IDs geht das aber immer noch am besten). Also einfach in den WHERE Teil: tabelle1.url = tabelle2.url
 
hi

danke dir aber dafür wo ich es gerade brauche ist Geschwindigkeit absolut nebensächlich das Script hat genug Zeit. Aber werde es mir auf jeden Fall merken

mfg

chris
 
Ein JOIN ist aber meine ich schneller als 'ne Sub-Query ;)

Dein Problem war, dass MySQL bei deiner Abfrage nicht weiß, woran er deine beiden Tabellen verbinden kann.
Wenn du also bei beiden Tabellen eine Spalte URL hast, dann kannst du die Tabellen z.B. anhand der URL verbinden (mit IDs geht das aber immer noch am besten). Also einfach in den WHERE Teil: tabelle1.url = tabelle2.url

Ja und nein ;)
in den pre-releases zu 5.0 (und im 4er Strang) waren Sub-Querys sehr sehr schlecht implementiert, also zu 99% langsamer als Joins.
Heute kommt es auf den Query.
Aber diese NOT IN()-Querys sind meist net dolle in der Ausführung
 
Auf eine Antwort von dir habe ich gewartet :p
neija das mysql-Signalwort im Titel sagt ja schon aus, dass ich da früher oder später reinschaue xD


Wie viele MySQL Bücher hast du nu eigentlich schon gefressen?^^
uff, das ist schwer zu zählen :LOL:
ne, waren nur 4 - dafür Unmengen aus den Blogs der Profi Optimierer und deren Powerpoint-Folien gelernt :biggrin:
und eben tief in die Architektur von MySQL eingearbeitet, wenn man versteht, was MySQL macht, ist es einfacher zu entscheiden, was performant und was nicht ist ^^