php.de

Zurück   php.de > Webentwicklung > Datenbanken

Datenbanken SQL und Co

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 01.08.2007, 19:03  
Benutzer
 
Registriert seit: 28.07.2007
Beiträge: 38
pPanther
Standard Komplexes Join Problem

Hallo alle zusammen!

Ich hoffe mir kann wer helfen:

Ich habe 2 MySQL Tabellen für ein Forum.
In der ersten Tabelle (foren_threads) stehen alle Themen.
In der 2ten Tabelle (foren_posts) stehen zu jedem Thema die passenden Antworten.
Beide Tabellen haben fast identische Spaltennamen.
Nun möchte ich mittels einer SQL Abfrage erreichen, dass er mir den jeweils letzten Datensatz aus einer der Tabellen holt und ausgibt.
Gibt es also eine Antwort, dann nimm die Antwort als Datensatz, gibt es keine Antwort, dann nimm das Thema als Datensatz.

Ich habe versucht es so zu realisieren:
PHP-Code:
$sql "SELECT foren_threads.ThreadID,
                       foren_threads.ForenID,
                       foren_threads.SubID,
                       DATE_FORMAT(foren_threads.erstellt, '%d.%m.%y | %H:%i') AS Erstellt,
                       foren_threads.BenutzerID,
                       foren_threads.Text,
                       foren_threads.Titel,
                       foren_posts.PostID,
                       foren_posts.ThreadID,
                       foren_posts.ForenID,
                       foren_posts.SubID,
                       DATE_FORMAT(foren_posts.erstellt, '%d.%m.%y | %H:%i') AS Erstellt,
                       foren_posts.BenutzerID,
                       foren_posts.Text,
                       BenutzerName
                FROM foren_threads
                  LEFT JOIN foren_posts
                    ON foren_posts.erstellt > foren_threads.erstellt
                    AND foren_posts.ThreadID = foren_threads.ThreadID
                  JOIN benutzer
                    ON foren_threads.BenutzerID = benutzer.BenutzerID
                    OR foren_posts.BenutzerID = benutzer.BenutzerID
                WHERE foren_threads.SubID = $subid OR foren_posts.SubID = $subid
                ORDER BY foren_threads.erstellt, foren_posts.erstellt
                DESC
                LIMIT 1"

Nun ist es aber so, dass das Ergebnis leer ist, wenn ein Thema noch keine Antwort hat, gibt es jedoch eine Antwort, dann habe ich eine Ergebnisressource.
Laut Manual ist aber der LEFT JOIN genau das was ich brauche, da ich ja nicht immer ein Ergebniss von der 2ten Tabelle erwarten kann.
Trotzdem ist das Ergebnis leer, was ich nicht verstehe.
Kann mir bitte jemand erklären, was hier mein Denkfehler ist?

Zur Info: Ich benutze PHP 5.1.1 mit MySQL 5.022 bei einem Webhoster

Danke im Voraus!
__________________
Ich bin gut schon gut, aber böse bin ich noch besser!
pPanther ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 01.08.2007, 19:55  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Stellt sich die Frage, warum du den ersten Post anders behandelst als die folgenden..
Zergling-new ist offline   Mit Zitat antworten
Alt 01.08.2007, 20:06  
Benutzer
 
Registriert seit: 28.07.2007
Beiträge: 38
pPanther
Standard

Zitat:
Zitat von Zergling
Stellt sich die Frage, warum du den ersten Post anders behandelst als die folgenden..

Hä, ich schnall momentan gar nix mehr.

Was meinst du mit "anders" behandeln?
__________________
Ich bin gut schon gut, aber böse bin ich noch besser!
pPanther ist offline   Mit Zitat antworten
Alt 01.08.2007, 20:16  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Warum speicherst du das Posting, das den Thread eröffnet in einer eigenen Tabelle?
Zergling-new ist offline   Mit Zitat antworten
Alt 01.08.2007, 20:35  
Benutzer
 
Registriert seit: 28.07.2007
Beiträge: 38
pPanther
Standard

Zwecks Übersichtlichkeit und weil ich es getrennt haben will.
Natürlich ginge es auch in einer Tabelle, aber das währe ja zu einfach :wink:

Aber bekomme ich auch eine Antwort auf meine eigentliche Frage, dem JOIN Problem?
__________________
Ich bin gut schon gut, aber böse bin ich noch besser!
pPanther ist offline   Mit Zitat antworten
Alt 01.08.2007, 21:10  
Erfahrener Benutzer
 
Registriert seit: 21.05.2008
Beiträge: 9.937
Zergling-new wird schon bald berühmt werden
Standard

Verstehe ich nicht, warum du das nicht verbesserst..

Vielleicht hilft dir der Ansatz, dass du NULL joinst, wenn kein passender Eintrag gefunden wird. Mittels IS NULL kannst du abfragen, ob ein Wert NULL ist und mit IF(bedingung, then, else) hast du auch noch das geeignete Konstrukt, bedingt Spalten zu selektieren.

Übrigens ist
Zitat:
ON foren_posts.erstellt > foren_threads.erstellt
AND foren_posts.ThreadID = foren_threads.ThreadID
etwas unglücklich gewählt. Schau her:
PHP-Code:
<?php
for ($zahl 1$zahl 10$zahl++) {
  if (
$zahl == && $zahl == 0) {
    
//..
  
}
}
?>
Das ist schlecht. Warum?
Beim Durchlauf 1..10 sind 10 + 5 Vergleiche notwendig.

Drehen wir die Reihenfolge der Bedingung um:
PHP-Code:
<?php
for ($zahl 1$zahl 10$zahl++) {
  if (
$zahl == && $zahl == 0) {
    
//..
  
}
}
?>
Oha, nurnoch 10 + 2 Vergleiche. Und das nur bei 10 Durchläufen (gleichzusetzen mit deinen Datensätzen in der DB).
Natürlich muss auch die Art des Vergleichs hinzugezogen werden, die ist hier aber identisch.

Ich will damit sagen, wenn du JOINst, nimm das KO-Kriterium zuerst (die Primärschlüsselverankerung, in deinem Fall foren_post.threadid = forenthread.threadid) und danach erst eventuelle Zusatzvergleiche.
Zergling-new ist offline   Mit Zitat antworten
Alt 02.08.2007, 08:19  
Benutzer
 
Registriert seit: 28.07.2007
Beiträge: 38
pPanther
Standard

Zitat:
Zitat von Zergling
Verstehe ich nicht, warum du das nicht verbesserst..
Ich dachte eben, wegen der Übersichtlichkeit, dass ich 2 Tabellen mache.
Aber je länger ich darüber nachdenke, desto blöder kommt auch mir meine Idee vor. Die Aufteilung ist nicht notwendig.

So wie es ausshieht habe ich generell einen Denkfehler in meiner DB Struktur fürs Forum.
Durch deine Aussage, dass ich NULL Joine, wurde mir bewusst, was ich da für einen Blödsinn mache.

Zitat:
Zitat von Zergling
Drehen wir die Reihenfolge der Bedingung um:
PHP-Code:
<?php
for ($zahl 1$zahl 10$zahl++) {
  if (
$zahl == && $zahl == 0) {
    
//..
  
}
}
?>
Ich will damit sagen, wenn du JOINst, nimm das KO-Kriterium zuerst (die Primärschlüsselverankerung, in deinem Fall foren_post.threadid = forenthread.threadid) und danach erst eventuelle Zusatzvergleiche
Danke für deine tolle Erklärung.

Nun weiß ich, dass mein eigentliches Problem nicht der Join ist, sondern meine DB Struktur. Daher werde ich das Problem an der Wurzel bekämpfen und die Tabellen zusammenlegen.
Die Codeänderung, die dadurch entsteht ist eh minimal, da ich ja eh alles in Klassen habe, und somit der Code nur an wenigen Stellen geändert werden muss.


Manchesmal denke ich einfach zu kompliziert....
__________________
Ich bin gut schon gut, aber böse bin ich noch besser!
pPanther ist offline   Mit Zitat antworten
Alt 03.08.2007, 23:16  
Moderator und Wett-König
 
Benutzerbild von dr.e.
 
Registriert seit: 21.05.2008
Beiträge: 3.633
PHP-Kenntnisse:
Fortgeschritten
dr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblickdr.e. ist ein Lichtblick
dr.e. eine Nachricht über Skype™ schicken
Standard

Hallo,

Zitat:
Ich dachte eben, wegen der Übersichtlichkeit, dass ich 2 Tabellen mache.
In der Objektorientierung hat man die Möglichkeit den ersten Eintrag in einer Liste - hier den Eröffnungs-Post - mit einer dedizierten Beziehung zum Tread-Objekt zu kennzeichnen. Dazu ist es jedoch nicht notwendig, einen eigene Tabelle zu erstellen. Aus diesem Grund würde ich das an deiner Stelle und wie Zergling schon sagte umstellen. Aber warum einfach, wenns auch kompliziert geht...
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> Adventure PHP Framework (APF))!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
[Erledigt] Galerie Problem... coraplanet PHP Tipps 2008 4 06.06.2008 13:42
[gelöst]LEFT JOIN, DINSTINCT und trotzdem doppelte?!?! stefanjann Datenbanken 10 06.02.2008 11:49
JOIN / LEFT JOIN und Co prinzli Datenbanken 12 05.11.2007 22:15
[Erledigt] wieder ein Problem bei phpmailer und smtp PHP Tipps 2006 24 07.02.2006 01:07
inner join aus db PHP Tipps 2006 8 22.01.2006 01:23
Select Problem Datenbanken 17 16.01.2006 21:54
[Erledigt] Abfrageproblem mit Inner Join Datenbanken 15 29.11.2005 18:17
[Erledigt] LEFT JOIN Query Bildung Datenbanken 6 04.11.2005 15:24
sql-Abfrage inner join - unerklärliches Problem havok Datenbanken 6 17.10.2005 14:32
[Erledigt] Problem mit Backslash Patrick Schwarz PHP Tipps 2005-2 5 26.07.2005 09:54
Join Problem Simon9990 PHP Tipps 2005-2 1 21.07.2005 22:15
Problem mit Where und Join Datenbanken 5 06.07.2005 18:05
[Erledigt] [LEFT JOIN] Verständnis Problem Datenbanken 6 17.06.2005 14:38
[Erledigt] Problem mit JOIN Datenbanken 7 27.08.2004 16:00
Problem mit alter JavaScript-Funktion woods PHP Tipps 2004 1 13.08.2004 13:34


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:00 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum

Creative Commons License
Dieser Inhalt ist unter einer Creative Commons-Lizenz lizenziert.