INNER JOIN Problem?

2Pac

Erfahrenes Mitglied
Hallo,

ich möchte aus 3 Tabellen die Daten auslesen, wobei ich die 1. Tabelle nur zum auslesen der userid's benötige, aus der 2. und 3. Tabelle aber die Daten auslese. Das ganze soll nach einem Wert aus Tabelle 2 sortiert werden. Es klappt aber nicht, ich bekomme die Meldung, dass mysql_fetch_object(): supplied argument is not a valid MySQL result resource in ....

Die Tabellen sehen wie folgt aus:

freundesliste:

id | userid | freundid

stadt:

id, userid, level, bevolkerung, hgeb, .................

user:

id, name, ...............

Mein Code sieht wie folgt aus:

PHP:
$login_id_freund = $_SESSION["user_id"];
$freundes_select = mysql_query("SELECT t.freundid FROM freundesliste AS t INNER JOIN stadt AS dt WHERE t.userid=$login_id_freund ORDER BY dt.bevolkerung DESC LIMIT 0,10");
echo "<div id='friends' class='right'><table class='data_table'>";
while ($f_row = mysql_fetch_object($freundes_select))
{
 $freund_id = $f_row ->t.freundid;
 $d_freundes_select = mysql_query("SELECT t.name, dt.bevolkerung, dt.level, dt.hgeb FROM stadt AS dt INNER JOIN user AS t WHERE t.id=$freund_id AND dt.userid=$freund_id");
 while ($f_row = mysql_fetch_object($d_freundes_select))
 {
  $freund_name = $f_row ->t.name;
  $freund_bev = $f_row ->dt.bevolkerung;
  $freund_lev = $f_row ->dt.level;
  $freund_hgeb = $f_row ->dt.hgeb;
  echo "<tr class='even' valign='top'><th valign='top'>$freund_name</th></tr><tr class='even' valign='top'><td valign='top'>Bevölkerung: $freund_bev<br/>Level: $freund_lev<br/>h. Gebäude: $freund_hgeb Meter</td></tr>";
 }
}
echo "</table></div>";

Was mach ich falsch? Danke im Voraus!
Ronny
 
Zuletzt bearbeitet:
Warum machst Du 2 Queries? Eine reicht doch:

PHP:
mysql_query("SELECT user.name, stadt.bevolkerung, stadt.level, stadt.hgeb
FROM freundesliste
LEFT JOIN user ON freundesliste.userid = user.id
LEFT JOIN stadt ON freundesliste.userid = stadt.userid
WHERE freundesliste.userid = '".mysql_real_escape_string($login_id_freund)."'
ORDER BY stadt.bevolkerung DESC LIMIT 0,10";
 
@Xanthos
Nicht besonders performant, da du zuerst alle Tabellen verknüpfst und dann den Filter setzt obwohl das gefilterte Feld der Schlüssel für die Verknüpfung ist.
Ja nach Datenmengen kann dies eine rechte bremse sein. Manchmal ist mehr SQL schneller

Ob sich der Aufwand lohnt, hängt von der grösse der Taebllen ab.

Er macht 2 QUeries, da das erste die Titelinformationen ausgibt, und das 2te die Details.

@2Pac
Die INNER JOIN sind falsch gebaut.
INNER JOIN table ON verknüpfungsbedinung
Oder du verzichtes auf das INNER JOIN und verknüpfst nur über die WHERE

Das erste Query könnte dann wie folgt aussehen (bitte die Beziehung (ON) überprüfen)
Code:
SELECT 
    f.freundid 
FROM 
    freundesliste AS f 
    INNER JOIN stadt AS s
        ON f.userid = s.userid 
WHERE
    f.userid=$login_id_freund 
ORDER BY 
    s.bevolkerung DESC

oder mittels WHERE verknüpft
Code:
SELECT 
    f.freundid 
FROM 
    freundesliste AS f, 
    stadt AS s
WHERE
    f.userid = s.userid
    AND f.userid = $login_id_freund 
ORDER BY 
    s.bevolkerung DESC


SLQ 2 könnte mit dem JOIN so aussehen
Code:
SELECT 
    u.name, 
    s.bevolkerung, 
    s.level, 
    s.hgeb 
FROM 
    stadt AS s 
    INNER JOIN user AS u 
        ON u.id = s.userid 
WHERE 
    s.userid=$freund_id

Ich empfehle dir, die SQL zuerst in eine Variable zu speichern. Im Problemfall kannst du diese mit echo ausgeben und mit phpMyAdmin in der DB prüfen.

Ich empfehle dir auch, für ein SQL mehrere Zeilen brauchen. Es wird einfach besser lesbar und man erkennt dann die Funktion und allenfalls Fehler viel schneller.
(Auch Leerzeilen zwieschendrin schaden nicht)
PHP:
...
$login_id_freund = $_SESSION["user_id"];

$sql = "SELECT 
            f.freundid 
        FROM 
            freundesliste AS f 
            INNER JOIN stadt AS s
                ON f.userid = s.userid 
        WHERE
            f.userid = {$login_id_freund} 
        ORDER BY 
            dt.bevolkerung DESC";
// zum Debuggen die folgende Zeile aktivieren und die Ausgabe in phpMyAdmin prüfen
// echo $sql
$freundes_select = mysql_query($sql);

echo "<div id='friends' class='right'><table class='data_table'>";
while ($f_row = mysql_fetch_object($freundes_select))
...
 
@yaslaw

Bei grösseren Datenmengen würde ich die Query natürlich entsprechend umstellen:

Code:
SELECT user.name, stadt.bevolkerung, stadt.level, stadt.hgeb 
FROM 
  (SELECT freundesliste.userid 
   FROM freundesliste 
   WHERE freundesliste.userid = '".mysql_real_escape_string($login_id_freund)."') AS freundesliste 
LEFT JOIN user ON freundesliste.userid = user.id 
LEFT JOIN stadt ON freundesliste.userid = stadt.userid   
ORDER BY stadt.bevolkerung DESC LIMIT 0,10

2 Queries und 2 verschachtelte while-Schleifen empfehle ich hingegen in keinem Fall. 10 User mit jeweils 10 Freunden, das ergibt bereits 101 einzelne Anfragen, mit denen man die DB "bombardiert".
 
@yaslaw
2 Queries und 2 verschachtelte while-Schleifen empfehle ich hingegen in keinem Fall. 10 User mit jeweils 10 Freunden, das ergibt bereits 101 einzelne Anfragen, mit denen man die DB "bombardiert".

Stimmt. Da macht es durchaus Sinn alles zusammenzufassen und im PHP-Code eval den Gruppenbruch zu evaluieren.
 
Relationale Datenbanken lösen Website-Probleme immer uneffektiv ;o)
Im grunde musst du dir da aber keine Sorgen machen. Auch wenn es jetzt sehr waage ist etc.: Bei einer MySQL-DB < 100MB kannst du noch so schlechte Queries schreiben und noch so viele Joins machen - da passiert eigentich nichts. 90% der Software da draußen ist einfach grottig und läuft trotzdem. Zumindest bis zu dem Punkt wo z.B. der große Besucheransturm kommt. Aber wie viele Seiten erleben das schon.
 
Zurück