[Mysql] Right Join Anweisung funzt net richtig!

pczombie

Banned
Registriert
Dez. 2005
Beiträge
201
Moin,

ich bin gerade dabei ein Forum zu Programmiern und hab en Problem beim Auslesen der Forenkategorien bzw der Foren Selbst.

Die 2 Tabellen:
  • cmp_forums_cats
  • cmp_forums
In der cmp_forums_cats gibts en Feld names "forumcatid", dieses gibts auch in cmp_forums.

Wenn ich nicht irre ist die cmp_forums tabelle abhängig von der cmp_forums_cats.
Also hab ich mir folgende Abfrage geschrieben:

PHP:
//Kategorien und Foren auslesen und auflisten
    $sql  = "SELECT *
            FROM cmp_forums_cats
            RIGHT JOIN cmp_forums
            ON (cmp_forums.forumcatid = cmp_forums_cats.forumcatid)";

So und jetzt das Problem:

Mir wird jede Kategorie 2 mal ausgeben, und ich weis net wieso! kann mir jemand helfen?

hier der link:
http://cms.itpro-forum.de/cmp/forum/
 
Kannst du ein bischen was über das Datenmodell posten, das dahintersteckt, und umschreiben, was du genau auslesen möchtest? Vielleicht könnte man eventuell ein anderes SQL-Statement basteln.
 
außerdem könnte ich mir gut vorstellen, dass in der ausgabe auch etwas nicht stimmt... wenn du dir mal dein forum anschaust, dann "staffelt" sich das ja mehr oder weniger... 0, 1, 2, 3,.. Foren
 
Könnte ein karthesisches Produkt sein.

Was genau willst Du erhalten? Reicht denn nicht bestimmte Spalten aus der Table forum und cat in jeweils einer Zeile als Ausgabe?

Hier mal ein Beispiel.

$sql = "SELECT f.*, c.catid c_catid, c.catname c_catname
FROM cmp_forums_cats c, cmp_forums f WHERE f.forumcatid = c.forumcatid";

Falls in beiden Tabellen gleiche Spaltennamen vorhanden sind, dann entweder nur 1 Spalte von beiden in den Select oder bei einer ein Alias vergeben, wie im Beispiel.
Falls noch Unterforen gibt, bräuchteste noch eine 2. Bedingung im WHERE.
Eventuell noch ein ORDER BY blabla hintendran, je nach Bedarf.

Aber wie gesagt, dazu bräuchten wir mehr Infos.
 
Zuletzt bearbeitet:
Wieso machst du überhaupt den right join? Nur mit einem inner join erhälst du eine eindeutige und korrekte zuordnung der Datensätze. Der right join klatscht dir ja nur die eine Tabelle an die andere dran. Probier es mal so:

PHP:
$sql  = "SELECT *
            FROM cmp_forums_cats
            INNER JOIN cmp_forums
            ON (cmp_forums.forumcatid = cmp_forums_cats.forumcatid)";
 
hmmm kommt es gleiche raus!

hier der source:
PHP:
<?php
    //Content Manager Profressional Bulletin Board
    //Copyright by Butschi 2005 - 2006
    //www.butcher.info.ms
    
    // ####################### SET PHP ENVIRONMENT ###########################
    error_reporting(E_ALL & ~E_NOTICE);
    
    define('DIR', '../');
    
    file_exists(DIR. "core/config.inc.php") ? require_once DIR. "core/config.inc.php" : print "Datei nicht gefunden";
    file_exists(DIR. "core/parser.php") ? include_once DIR. "core/parser.php" : print "Datei nicht gefunden";
    file_exists(DIR. "core/functions.php") ? include_once DIR. "core/functions.php" : print "Datei nicht gefunden";
    file_exists(DIR. "core/core.php") ? include_once DIR. "core/core.php" : print "Datei nicht gefunden";
    file_exists(DIR. "core/classes/class.stats.php") ? include_once DIR. "core/classes/class.stats.php" : print "Datei nicht gefunden";    
    
    eval ("\$forum_content .= \"".gettemplate("forumhome_forumlist_header")."\";");
    
    //Kategorien und Foren auslesen und auflisten
    $sql  = "SELECT *
            FROM cmp_forums_cats
            LEFT JOIN cmp_forums
            ON (cmp_forums.forumcatid = cmp_forums_cats.forumcatid)";    
    
    print $sql;    
        
    $result = mysql_query($sql) or die (mysql_error());                        
    $result_count =  mysql_num_rows($result);
    while($row = mysql_fetch_array($result))
    {
        $forumcatid             = $row['forumcatid'];
        $forumcatname            = $row['forumcatname'];
        $forumcatdescription     = $row['forumcatdescription'];    
        $cmpbb_forum_id            = $row['forumid'];
        $cmpbb_forumtitle        = $row['forumtitle'];
        $cmpbb_forumdescription    = $row['forumdescription'];
        $cmpbb_forumthreads        = $row['forumthreads'];
        $cmpbb_forumposts        = $row['forumposts'];
        $cmpbb_forumlastpost    = $row['forumlastpost'];
        
        //Gesamtanzahl an Threads ermitteln            
        $sql_count_topics = mysql_query("SELECT    threadid FROM cmp_forums_threads WHERE forumid = '$cmpbb_forum_id'") or die (mysql_error());;
        $count_threads = mysql_num_rows($sql_count_topics);
        
        //Gesamtanzahl an Beitägen ermitteln für das jeweilige Forum ermitteln
        $sql_count_posts = mysql_query("SELECT postid FROM cmp_forums_posts WHERE forumid = '$cmpbb_forum_id'") or die (mysql_error());
        $count_posts = mysql_num_rows($sql_count_posts);                
        
        
        if($cmpbb_forumposts == "0")
        {
            $cmpbb_forumlastposts = "Keiner";
        }
                            
        eval ("\$forum_content .= \"".gettemplate("forumhome_forumlist_cat_postbit")."\";");
        eval ("\$forumhome_forums .= \"".gettemplate("forumhome_forumlist_postbit")."\";");
    }    
    
    //Statistiken Anzeigen    
    eval ("\$footer_stats .= \"".$stats->counttopics($topics)."\";");
    eval ("\$footer_stats_posts .= \"".$stats->countposts($posts)."\";");
    eval ("\$footer_stats_users .= \"".$stats->countusers($users)."\";");
    eval ("\$last_reg_user .= \"".$stats->newestuser($user, $newuser)."\";");
    //Statistiken Ende
    
    eval ("parse(\"".gettemplate("forum_layout")."\");");

?>
 
Relict schrieb:
Könnte ein karthesisches Produkt sein.

Was genau willst Du erhalten? Reicht denn nicht bestimmte Spalten aus der Table forum und cat in jeweils einer Zeile als Ausgabe?

Hier mal ein Beispiel.

$sql = "SELECT f.*, c.catid c_catid, c.catname c_catname
FROM cmp_forums_cats c, cmp_forums f WHERE f.forumcatid = c.forumcatid";

Falls in beiden Tabellen gleiche Spaltennamen vorhanden sind, dann entweder nur 1 Spalte von beiden in den Select oder bei einer ein Alias vergeben, wie im Beispiel.
Falls noch Unterforen gibt, bräuchteste noch eine 2. Bedingung im WHERE.
Eventuell noch ein ORDER BY blabla hintendran, je nach Bedarf.

Aber wie gesagt, dazu bräuchten wir mehr Infos.
hey, ja ich weis! guck dir mal mein Post an wo ich zuletzt gmacht hab. Vielleicht hilft der Weiter.

Es sind 2 Templates die ich inneinnader reinparse. Genau das wird der Fehler sein schätze ich.

So sollte es normal aussehen:
|-- Allgemein (Kategorie)
| |- Smalltalk (Forum)
| |- Eingangshalle (Forum)
|-- Feedback (Kategorie)
| |- Verbesserungsvorschläge (Forum)
 
Zuletzt bearbeitet:
Normalerweise hat doch jedes Forum die ID der jeweiligen übergeordneten Kategorie.
Also vergleicht man die forumcatid in der Tabelle wo die foren stehen mit der eindeutigen id der Kategorie-Tabelle.

Ich kann mir nur erklären das mysql abdreht, weil Du beim Select ein * hast, aber in beiden Tabellen Spalten gleichen Namens vorkommen.
Glaube das geht net, probier mal wie in meinem Beispiel jede einzelne benötigte Spalte von beiden Tabellen (namensgleiche mit Alias-Namen) im SELECT aufzurufen.

Kannste auch analog mit left/ right - joins machen. Da Du ja sicher auch "leere" Kategorien mit ausgeben willst. ;)

Ansonsten wie gesagt, poste mit mal die Tablestruktur von beiden. Denn dann muss in der Struktur/ Spalten/ Keys was unlogisch sein.
 
hier die screenis :)
 

Anhänge

  • cmp_forums.JPG
    cmp_forums.JPG
    58,8 KB · Aufrufe: 234
  • cmp_forums_cats.JPG
    cmp_forums_cats.JPG
    42,9 KB · Aufrufe: 204
Ich würde an deiner Stelle so vorgehen, dass du in mehreren Schritten die Daten von der Datenbank liest.
Erstmal alle Einträge aus cmp_forums_cats lesen. Dann für jeden hier gefundenen Eintrag alle Einträge aus cmp_forums holen, die von dem momentan bearbeiteten Eintrag aus cmp_forums_cats abhängen.

Soll heissen:
PHP:
$sql_cats = "SELECT * FROM cmp_forums_cats";
$result_cats = mysql_query($sql_cats) or die (mysql_error());
while($row_cats = mysql_fetch_array($result_cats)) {
  $cat_id = $row_cats['forumscatid'];
  $sql_forums = "SELECT * FROM cmp_forums cf WHERE cf.forumcatdid = $cat_id";
  ...
}
Mit der Art fährst du besser, als mit dem, was du bisher versuchst.
 
@Cobinja
Merke: Niemals innerhalb von Schleifen SQL Abfragen machen! ^^
Es gibt immer eine andere Lösung. :D

@zombie
Hmm sieht soweit nicht wirklich schlecht aus.
Nur mache mal bitte bei der cmp_forum-table aus der forumcatid einen int(10) + index
Das ist nicht nur schneller, sondern auch kein Type-Missmatch mehr beim Vergleichen.

Und bei der forum_order_id am besten gleich auch. da reicht ein tinyint(4)
Bei den cats wäre evt. auch noch eine cat_order_id sinnvoll?
Warum Du den schwedischen Zeichensatz hast, ist mir allerdings unklar, nungut. ;)

Wie gesagt, der left join in meinem Beispiel sollte stimmen,. Der Fehler muss woanders liegen, evt. in den Spalteninhalten selber.
Naja beseitige erstmal die obigen Mankos und führe die Spalten die Du brauchst am besten einzeln auf im Select ohne *.

also:

$sql = "SELECT f.forumid, f.forumtitle, f.forumdescription, f.forumthreads, f.forumposts, f.forumlastpost,
c.forumcatid, c.forumcatname, c.forumcatdescription, c.forumchildids
FROM cmp_forums_cats c LEFT JOIN cmp_forums f ON f.forumcatid = c.forumcatid
ORDER BY f.forum_order_id";
 
Zuletzt bearbeitet:
Cobinja schrieb:
Ich würde an deiner Stelle so vorgehen, dass du in mehreren Schritten die Daten von der Datenbank liest.
Erstmal alle Einträge aus cmp_forums_cats lesen. Dann für jeden hier gefundenen Eintrag alle Einträge aus cmp_forums holen, die von dem momentan bearbeiteten Eintrag aus cmp_forums_cats abhängen.

Soll heissen:
PHP:
$sql_cats = "SELECT * FROM cmp_forums_cats";
$result_cats = mysql_query($sql_cats) or die (mysql_error());
while($row_cats = mysql_fetch_array($result_cats)) {
  $cat_id = $row_cats['forumscatid'];
  $sql_forums = "SELECT * FROM cmp_forums cf WHERE cf.forumcatdid = $cat_id";
  ...
}
Mit der Art fährst du besser, als mit dem, was du bisher versuchst.
so hatte ichs schon ;) is ekelhaft anzusehen des ganze :(
deswegen leftjoin etc
 
Ich würde es keineswegs als ekelhaft anzusehen bezeichnen, sondern genau das Gegenteil. Du hast vor allem eine klare Gliederung, in welchem Result du Einträge aus welcher Tabelle hast.
 
Zurück
Oben