Problem beim joinen von mehreren Tabellen
lima-city → Forum → Programmiersprachen → PHP, MySQL & .htaccess
abfrage
aufruf
ausgeben
benutzer
bewertung
code
datenbank
einzelnen tabellen
ergebnis
flag
jeweilige thema
kategorie
klausel
not
null
problem
summe
tabelle
teddy
url
-
Ich habe Probleme bei den Abfragen von MySQL-Tabellen, die ich mittels JOIN-Anweisungen miteinander verknüpfe. Im Grunde versuche ich alle Einträge aus einer Tabelle "Themen" abzufragen und - soweit vorhanden - die zusätzlichen Angaben, die in weiteren Tabellen eingetragen sind, diesen Einträgen zuzuordnen.
Ich würde mich sehr freuen, wenn ihr mich bei meinem Problem unterstützt könnt und wir gemeinsam eine Problemlösung erarbeiten können. Vielleicht hilft dies auch Anderen weiter, die mit vergleichbarer Problematik konfrontiert sind/werden.
Hier sind zunächst die verwendeten Tabellen angegegebn:
-- -- Tabellenstruktur für Tabelle `Themen` -- CREATE TABLE IF NOT EXISTS `Themen` ( `id` int(10) NOT NULL AUTO_INCREMENT, `Titel` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `Autor` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `Themen-Bild` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `Sprache` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `flag` int(3) NOT NULL, `Datum` datetime DEFAULT NULL, `Ansichten` int(10) NOT NULL, PRIMARY KEY (`id`), FULLTEXT KEY `SEARCH` (`Titel`,`Autor`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; -- -------------------------------------------------------- -- -- Tabellenstruktur für Tabelle `Themen_Kategorie` -- CREATE TABLE IF NOT EXISTS `Themen_Kategorie` ( `id` int(10) NOT NULL AUTO_INCREMENT, `Themen-ID` varchar(20) COLLATE utf8_unicode_ci NOT NULL, `Kategorien-ID` int(10) NOT NULL, PRIMARY KEY (`id`,`Themen-ID`,`Kategorien-ID`), KEY `fk_Themen-ID` (`Themen-ID`), KEY `fk_Kategorien-ID` (`Kategorien-ID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; -- -------------------------------------------------------- -- -- Tabellenstruktur für Tabelle `Themen_keywords` -- CREATE TABLE IF NOT EXISTS `Themen_keywords` ( `id` int(10) NOT NULL AUTO_INCREMENT, `Themen-ID` varchar(20) COLLATE utf8_unicode_ci NOT NULL, `keyword` varchar(255) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`,`Themen-ID`), KEY `fk_Themen-ID` (`Themen-ID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; -- -------------------------------------------------------- -- -- Tabellenstruktur für Tabelle `Themen_Bewertung` -- CREATE TABLE IF NOT EXISTS `Themen_Bewertung` ( `id` int(10) NOT NULL AUTO_INCREMENT, `Themen-ID` varchar(20) COLLATE utf8_unicode_ci NOT NULL, `Benutzer-ID` int(10) NOT NULL, `Bewertung` int(2) NOT NULL, `Kommentar` text COLLATE utf8_unicode_ci NOT NULL, `Datum` datetime DEFAULT NULL, `flag` int(3) NOT NULL, PRIMARY KEY (`id`,`Themen-ID`,`Benutzer-ID`), KEY `fk_Themen-ID` (`Themen-ID`), KEY `fk_Benutzer-ID` (`Benutzer-ID`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ; -- -------------------------------------------------------- -- -- Tabellenstruktur für Tabelle `Kategorien` -- CREATE TABLE IF NOT EXISTS `Kategorien` ( `id` int(20) NOT NULL AUTO_INCREMENT, `Name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `Untergeordnet_zu_Kategorien-ID` int(20) NOT NULL, `flag` int(3) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;
- Es sollen alle Einträge/Themen aus der Tabelle "Themen" angezeigt werden.
- Ein Thema kann mehreren Kategorien zugeordnet sein. Daher die zusätzliche Tabelle "Themen_Kategorie". In dieser erfolgt die Verknüpfung des Themas mit einer oder mehreren Kategorien.
- Ebenso können mehrere Bewertungen für ein Thema vorhanden sein. Diese sollen in der Abfrage gruppiert werden, so dass die Anzahl der Bewertungen und der errechnete Bewertungsquotient (Bewertungspunkte / Anzahl der Bewertungen) ausgegeben werden. Es soll auch der Fall berücksichtigt werden, dass keine Bewertung für ein Thema vorliegt.
- Schlüsselwörter (Keywords) können ebenfalls mehrfach für ein Thema eingetragen werden oder auch die gleichen Schlüsselwörter für unterschiedliche Themen. Auch hier soll der Fall berücksichtigt werden, dass keine Schlüsselwörter für ein Thema vorliegen.
Bisher habe ich folgende Abfrage erstellen können. Komme aber leider nicht zu dem gewünschten Ergebnis und die Abfragedauer ist immens lang:
SELECT Themen.*, SUM(Themen_Bewertung.Bewertung) as Bewertungen, COUNT(Themen_Bewertung.Themen-ID) as Anzahl_Bewertungen, (SUM(Themen_Bewertung.Bewertung) DIV COUNT(Themen_Bewertung.Themen-ID)) as Bewertungsergebnis, Themen_Bewertung.*, Themen_keywords.* FROM Themen LEFT JOIN Themen_Bewertung ON Themen.id = Themen_Bewertung.Themen-ID LEFT JOIN Themen_Kategorie ON Themen.id = Themen_Kategorie.Themen-ID LEFT JOIN Themen_keywords ON Themen.id = Themen_keywords.Themen-ID GROUP BY Themen.id
- - - - - - - - - - - - - - - - - - -
Dieses folgende Problem bitte noch nicht berücksichtigen. Das oben geschilderte Problem ist von primärem Interesse:
Zusätzlich sollte, wenn überhaupt möglich, eine Verschachtelung innerhalb der Tabelle Kategorien erfolgen. Zu diesem Zweck wurde eine Spalte ("Untergeordnet_zu_Kategorien-ID") eingefügt, die die ID der übergeordneten Kategorie enthält. In der Abfrage sollen dann hierarchisch geordnet Themen angezeigt werden, d.h. Themen, die innerhalb einer Unterkategorie zugeordnet sind, sollen auch innerhalb der übergeordneten Tabelle angezeigt werden.
-
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage
-
Wenn ich das richtig sehe, lässt Du alle Bewertungen ausgeben, nicht nur die für das jeweilige Thema.
-
tobiworlds schrieb:
Wenn ich das richtig sehe, lässt Du alle Bewertungen ausgeben, nicht nur die für das jeweilige Thema.
Das siehst du richtig..
Um dein Problem zu Meistern wäre es sinnvoll vorher das Thema auszulesen und dann mittels einer WHERE Klausel das ganze so abfangen, dass auch NUR die Einträge für das entsprechende Thema abgefangen werden. ;) Sollte relativ einfach sein, da du wohl beim Aufruf der Seite schon nach dem Thema fragst, wenn man deine Struktur mal unter die Lupe nimmt, oder?
BTW: Verwirrt dich das nicht, dass jedesmal nach "Themen_" das nächste Wort groß geschrieben ist, nur bei "Themen_keywords" nicht? -
tobiworlds schrieb:
Wenn ich das richtig sehe, lässt Du alle Bewertungen ausgeben, nicht nur die für das jeweilige Thema.
Es sollen auch alle Themen ausgegeben werden und eben auch zusammen mit den jeweiligen Bewertungen. So gesehen eine Übersicht aller Themen.
kill-a-teddy schrieb:
Das siehst du richtig..
Um dein Problem zu Meistern wäre es sinnvoll vorher das Thema auszulesen und dann mittels einer WHERE Klausel das ganze so abfangen, dass auch NUR die Einträge für das entsprechende Thema abgefangen werden. ;) Sollte relativ einfach sein, da du wohl beim Aufruf der Seite schon nach dem Thema fragst, wenn man deine Struktur mal unter die Lupe nimmt, oder?
Auf diese Weise wäre es natürlich kein Problem. Wie oben erwähnt, soll eine Übersicht aller Themen angezeigt werden, die in der Datenbank enthalten sind. Eine Abfrage per WHERE-Klausel folgt dann erst später, um z.B. nach Kategorien zu filtern.
Es soll alles richtig zugeordnet ausgegeben werden.
kill-a-teddy schrieb:
BTW: Verwirrt dich das nicht, dass jedesmal nach "Themen_" das nächste Wort groß geschrieben ist, nur bei "Themen_keywords" nicht?
Weil es eine engl. Bezeichnung ist - und auch die einzige hier verwendete -, habe ich es absichtlich klein geschrieben. Mich stört es nicht. Wenn es aber die Übersichtlichkeit beeinträchtigt, kann ich es auch groß schreiben.
Beitrag zuletzt geändert: 20.11.2012 15:53:05 von readbooks -
Das musst ganz alleine Du wissen, wie Du was schreibst, aber ein Tipp wäre, alles klein zu schreiben, dann kann es nicht zu Problemen durch Schusselfehler kommen.
Das Problem bei der Berechnung der Bewertung ist, dass Du die einzelnen Bewertungen alle zusammen ausgibst und somit natürlich nicht die richtigen Ergebnisse für die Durchschnittsbewertung eines Themas bekommen kannst, sondern immer irgendeine sinnlose Zahl. -
readbooks schrieb:
Es sollen auch alle Themen ausgegeben werden und eben auch zusammen mit den jeweiligen Bewertungen. So gesehen eine Übersicht aller Themen.
Ok, ich bin total verwirrt.. Wo ist denn nun dein Problem, wenn doch alles klappt wie du es haben wolltest? Bitte erkläre mal genau, was du für ein Problem hast... -
tobiworlds schrieb:
Das musst ganz alleine Du wissen, wie Du was schreibst, aber ein Tipp wäre, alles klein zu schreiben, dann kann es nicht zu Problemen durch Schusselfehler kommen.
OK.
tobiworlds schrieb:
Das Problem bei der Berechnung der Bewertung ist, dass Du die einzelnen Bewertungen alle zusammen ausgibst und somit natürlich nicht die richtigen Ergebnisse für die Durchschnittsbewertung eines Themas bekommen kannst, sondern immer irgendeine sinnlose Zahl.
Nein, genau das soll ja mit dem jeweiligen JOIN nicht geschehen. Es werden alle Bewertungen jedes Themas zu dem jeweiligen Thema zugeordnet und die Summe von diesen zugeordneten Bewertungen berechnet:
... LEFT JOIN Themen_Bewertung ON Themen.id = Themen_Bewertung.Themen-ID ...
kill-a-teddy schrieb:
Ok, ich bin total verwirrt.. Wo ist denn nun dein Problem, wenn doch alles klappt wie du es haben wolltest? Bitte erkläre mal genau, was du für ein Problem hast...
Das Problem ist ja, dass es eben nicht klappt. Ich habe eigentlich alles im ersten Beitrag erklärt. Falls es Unklarheiten gibt, bitte ich auf diese hinzuweisen, damit ich mich nochmal erklären kann. -
readbooks schrieb:
Das Problem ist ja, dass es eben nicht klappt. Ich habe eigentlich alles im ersten Beitrag erklärt. Falls es Unklarheiten gibt, bitte ich auf diese hinzuweisen, damit ich mich nochmal erklären kann.
Jetzt habe ich es kapiert :D (glaub ich)..
Left join ließt nur alle spalten aus, zum summieren verwendet man einen inner join ;) -
kill-a-teddy schrieb:
Jetzt habe ich es kapiert :D (glaub ich)..
OK.
In erster Linie besteht das Problem darin, dass ich nicht die richtige Kreuztabelle erhalte. Also die Tabelle, die aus den einzelnen Tabellen zusammengefügt wird. Ich vermute, dass durch diese Abfrage die gleichen Zeilen mehrfach erzeugt werden. Dies sollte natürlich nicht so sein. Daher bitte ich um Hilfe, wie die Abfrage am besten modifiziert werden kann, um das gewünschte Ergebnis in angemessener Abfragezeit zu erhalten.
kill-a-teddy schrieb:
Left join ließt nur alle spalten aus, zum summieren verwendet man einen inner join ;)
Sobald eine vernünftige Kreuztabelle erstellt wird, denke ich, dass das summieren nur noch eine Nebensache sein wird. Daher sollte dieser Punkt im Moment nicht so sehr von zentraler Bedeutung sein. -
Lies mal ab hier abwärts: http://aktuell.de.selfhtml.org/artikel/datenbanken/joins/#inner_join, vielleicht findest Du etwas Hilfreiches. Ich verstehe auf jeden Fall Dein Problem nicht mehr wirklich.
-
readbooks schrieb:
In erster Linie besteht das Problem darin, dass ich nicht die richtige Kreuztabelle erhalte. Also die Tabelle, die aus den einzelnen Tabellen zusammengefügt wird. Ich vermute, dass durch diese Abfrage die gleichen Zeilen mehrfach erzeugt werden. Dies sollte natürlich nicht so sein. Daher bitte ich um Hilfe, wie die Abfrage am besten modifiziert werden kann, um das gewünschte Ergebnis in angemessener Abfragezeit zu erhalten.
Sobald eine vernünftige Kreuztabelle erstellt wird, denke ich, dass das summieren nur noch eine Nebensache sein wird. Daher sollte dieser Punkt im Moment nicht so sehr von zentraler Bedeutung sein.
Du hast ja keine Kreuz Tabelle, du summierst einfach alles. Du müsstest das "SUM" komplett weg lassen und aus dem left einen inner join machen :P
Oder wenn du es gar nicht schaffst, dann ließ einfach alle tabellen aus und summier sie mit php, das spaart eh Zeit bei der Abfrage ^^ -
tobiworlds schrieb:
Lies mal ab hier abwärts: http://aktuell.de.selfhtml.org/artikel/datenbanken/joins/#inner_join, vielleicht findest Du etwas Hilfreiches. Ich verstehe auf jeden Fall Dein Problem nicht mehr wirklich.
Vielen Dank. Hier steht ja auch die richtige Bezeichnung: kartesisches Produkt. Das meinte ich mit der Kreuztabelle.
kill-a-teddy schrieb:
Du hast ja keine Kreuz Tabelle, du summierst einfach alles. Du müsstest das "SUM" komplett weg lassen und aus dem left einen inner join machen :P
Mit Kreuztabelle meinte ich das kartesische Produkt, dass durch das zusammenfügen (joinen) der einzelnen Tabellen entsteht. Summiert werden eigentlichen nur die Bewertungen. Die Summe wird dann dem jeweiligen Thema zugeordnet.
kill-a-teddy schrieb:
Oder wenn du es gar nicht schaffst, dann ließ einfach alle tabellen aus und summier sie mit php, das spaart eh Zeit bei der Abfrage ^^
Die Summe zu berechnen ist kein Problem. Die Schwierigkeit, die ich habe, besteht darin, dass ich die einzelnen Tabellen nicht richtig miteinander verknüpfen (joinen) kann. -
Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!
lima-city: Gratis werbefreier Webspace für deine eigene Homepage