left & right join

caramba12321

blödefragensteller
Hallo Leute, ich hab mal wieder ein kleines Problemchen:

Also ich arbeite gerade an einem neuen Forum für eine ca 3000. Mann Community, da unser altes Forum schon ziemlich veraltet ist, programmiere ich jetzt eins das auf smarty,css und php basiert. Ich versuche so viel wie möglich oop zu machen.

Also zu meiner Frage:
Ich habe eine tabelle namens stl_forum_posts und eine namens stl_forum_edits.
In der posts steht immer der aktuelle Post zu einem Thread drinne und wenn jetzt z.B. jemand einen Edit macht , wird der alte Post in stl_forum_edits verschoben und der neue in stl_forum_posts geschrieben , was ja auch einwandfrei klappt.
ICh mache das ganze nur, damit ein Moderator später alle edits einsehen kann.
Also wenn ich nun einen Thread öffne werden dazu die Beiträge geladen, ich habe in stl_forum_posts ebenfalls die Anzahl der edits festgehalten und nun wollte ich folgendes machen. Ich speichere in stl_forum_edits die id des editers ( kann ja auch sein das ein Moderator den Post geeditet hat ), übrigens speichere ich immer nur die id von der Person, die als letztes einen Edit gemacht hat. Nun will ich in einem query, den namen des editers aus stl_forum_user laden, wenn ein Edit schon stattgefunden hat, ist das auch kein Problem, wenn nicht, dann liefert er mir aber null; zurück also kein Datensatz und der Query wird nicht weiter ausgeführt. Ich habe gehört mann kann sowas mit Left und Right join machen, weiss aber nicht genau wie das geht. Ich hänge den Query mal in einer sehr vereifnachten version an, vllt kann jemand das ja einfach mal in einer Wortgleichung einbauen oder jemand mir erklären wie das geht.

PHP:
function load() {
            global $db;
                $db->query("
                    SELECT
                        p.*,
                        u.nickname as posternickname
                    FROM
                        ".TABLE_FORUM_POSTS." AS p,
                        ".TABLE_USER." AS u
                    WHERE
                        p.id = ".$db->esc($this->id)."
                    AND
                        u.id = p.poster_id
                ");
                
                $this->fill($db->getFirstObject());
        }

Es soll also noch rein, editernickname from TABLE_USER , ich hoffe ich konnte mein Problem verständlich erläutern, ihr werdet sehen das ich nur mit Objekten programmiere, z.B. sieht mann das schon daran, dass ich ein fill , ein load und ein save Objekt habe. Ich kann jedem emofehlen mit Objekten zu arbeiten, ist am Anfang zwar mehr Arbeit , spart später aber einiges. Ich z.B. habe Für Threads, Posts, Edit immer ein jeweils eigenes Objekt.

Gruss
Caramba

edit: achja nicht wundern, die ganzen id`s der Posts lese ich vorher aus und die loadfunktion wird dann einfach in eine foreach(); Schleife ausgeführt.


edit2: ich weiss , mit 2 Querys geht das ganz einfach, ist aber nicht professionell ;)
 
Zuletzt bearbeitet:
Hallo,

mit einem LEFT JOIN würde es folgendermaßen aussehen:

PHP:
function load() {
            global $db;
                $db->query("
                    SELECT
                        p.*,
                        u.nickname as posternickname
                    FROM
                        ".TABLE_FORUM_POSTS." AS p,
                    LEFT JOIN
                        ".TABLE_USER." AS u ON (u.id = p.poster_id)
                    WHERE
                        p.id = ".$db->esc($this->id)
                );
                
                $this->fill($db->getFirstObject());
        }

Übrigens könnte man dein Datenbankschema noch etwas optimieren. Die Anzahl der Editiervorgänge in der Posts-Tabelle zu speichern, ist beispielsweise redundant (die Information ist auch schon in der Edits-Tabelle enthalten).

Grüße,
Matthias
 
Nein, die anzahl der Edits wird im eigendlich Post also in stl_forum_posts gespeichert, sonst würde ich ja unnötigen Traffic erzeugen ;)
Danke erstmal für deinen Beitrag, aber du hast mich nicht richtig verstanden.
So wie du das da geschrieben hat, gibt das ja keinen Sinn, da ich der Posternickname ja immer vorhanden ist.
Ich möchte zusätzlichen noch den editernickname aus der stl_user Tabelle laden, also den Namen der ID des letzten Editers in stl_forum_posts, also last_editer_id .

Gruss
Caramba
 
Hallo,

caramba12321 hat gesagt.:
Nein, die anzahl der Edits wird im eigendlich Post also in stl_forum_posts gespeichert, sonst würde ich ja unnötigen Traffic erzeugen ;)
So wie ich das sehe, gibt es für jeden Editiervorgang einen entsprechenden Eintrag in stl_forum_edits. Darüber lässt sich dann auch die Anzahl der Editierungen eines bestimmten Posts ermitteln. Welcher zusätzliche Traffic soll denn da erzeugt werden?

Danke erstmal für deinen Beitrag, aber du hast mich nicht richtig verstanden.
So wie du das da geschrieben hat, gibt das ja keinen Sinn, da ich der Posternickname ja immer vorhanden ist.
Na sag das doch gleich ;) Du hast leider einige (meiner Meinung nach) unrelevante Informationen in einen Ursprungsbeitrag gepackt, da tut man sich dann schon mal schwer, die Kernfrage herauszupicken. Am einfachsten wäre es gewesen, die entsprechenden Tabellen und Verknüpfungen schematisch zu beschreiben, z.B. so:

Code:
+---------------------+           +------------------+
|  stl_forum_posts    |           |  stl_forum_user  |
+---------------------+           +------------------+
| id             (PK) | n:1+---+->| id          (PK) |
| poster_id      (FK) |----+   |  | nickname         |
| ...                 |   n:1  |  | ...              |
| last_editor_id (FK) |--------+  +------------------+
+---------------------+

Gesucht: die Abfrage so erweitern, dass mir, falls last_editor_id nicht NULL ist, der entsprechenden Wert von nickname aus stl_forum_user (z.B. mit Alias last_editor_nickname) mit zurückgeliefert wird. Ist last_editor_id NULL, so soll auch last_editor_nickname NULL sein.

Dass du mit Objekten arbeitest oder dass es eine Tabelle namens stl_forum_edits gibt, die mit stl_forum_posts abgeglichen wird, interessiert ja zunächst nicht :)

Aber jetzt zur (hoffentlichen) Lösung des Problems:
PHP:
function load() {
            global $db;
                $db->query("
                    SELECT
                        p.*,
                        up.nickname AS posternickname,
                        ue.nickname AS last_editor_nickname
                    FROM
                        ".TABLE_FORUM_POSTS." AS p,
                    INNER JOIN
                        ".TABLE_USER." AS up ON (up.id = p.poster_id)
                    LEFT JOIN
                        ".TABLE_USER." AS ue ON (ue.id = p.last_editor_id)
                    WHERE
                        p.id = ".$db->esc($this->id)
                );
                
                $this->fill($db->getFirstObject());
        }

Ungetestet, kann also noch voller Tippfehler stecken.

Grüße,
Matthias
 
Ahh genau so funtkionierte das, naja immerhin gibt es hier Leute die sich gut mit Sql auskennen ;) Ich dank dir soweit erstmal, kannst ja mal ein blick reinwerfen wenn ich fertig bin ;)
 
Zurück