inner join bis heute nicht begriffen
Übeleis Markus
- asp.net
Guten Abend.
Gleich mal vorhin weg: ja, ich habe mir bereits umgesehen, auch hier.
Ziel: der inner join Befehl...er geht nicht in mein Hirn rein.
Es handelt sich um ein kleines von mir selber programmiertes Forum (unabhängig dessen, ob es jemand brauchen könnte oder nicht, es dient zum Selbststudium)
Problem: Ich möchte auf der Hauptseite, (auf welcher die Foren angezeigt werden), eine zelle haben, die den letzten Beitrag aussagt. Das Problem liegt jetzt darin, zu filtern: ist der letzte Beitrag ein neues Thema, oder nur eine antwort, auf ein bestehendes Thema.
--------
Tabellen:
[Themen]
id, forum_id, themen_titel, themen_datum, themen_uhrzeit, themen_inhalt, usw.
[Antwort]
id, themen_id, antwort_datum, antwort_uhrzeit, antwort_inhalt, usw
.
.
.
Nun möchte ich 2 Dinge mit meinem Posting bezwecken:
1x mal den inner join befehl verstehen
2x diesen hier vielleicht sogar zum einsatz bringen.
Lösung: Wie kann ich das letzte Posting in diesem Forum herausfinden.
Ich bin für jede hilfe dankbar.
mfg Übeleis Markus
Moin!
Problem: Ich möchte auf der Hauptseite, (auf welcher die Foren angezeigt werden), eine zelle haben, die den letzten Beitrag aussagt. Das Problem liegt jetzt darin, zu filtern: ist der letzte Beitrag ein neues Thema, oder nur eine antwort, auf ein bestehendes Thema.
Tabellen:
[Themen]
id, forum_id, themen_titel, themen_datum, themen_uhrzeit, themen_inhalt, usw.[Antwort]
id, themen_id, antwort_datum, antwort_uhrzeit, antwort_inhalt, usw
Frage zuerst: Ist dein "Forum" ein echtes Forum oder nur ein Board? Je nachdem ist deine Frage nämlich komplex oder sehr komplex. Wenn ich mir deine Tabellen so ansehe, dann sieht es so aus, als ob du nur ein Board hast.
Dein Problem läßt sich ganz simpel dadurch lösen, dass du (was mir in deiner Datenstruktur auf den ersten Blick fehlt) ein Feld hinzufügst, in dem verzeichnet ist, auf welche andere Nachricht die jeweilige Antwort eine Nachricht ist. Logischerweise haben Nachrichten, die ein neues Thema starten, dann keine Angabe in diesem Feld und können sehr leicht herausgefiltert werden (wenn du ein Board hast, reicht auch einfach ein simples Flag "ist neues Thema" vs. "ist Antwort"). Wie kriegst du denn derzeit alle Antworten entsprechend ihrer Aufreihung untereinander?
Diese Vorgehensweise ist insofern auch besser, weil sie wesentlich performanter sein dürfte als irgendein JOIN. Das hilft dir zwar nicht beim Verstehen von INNER JOINs, aber es löst dein Problem. :)
- Sven Rautenberg
Frage zuerst: Ist dein "Forum" ein echtes Forum oder nur ein Board? Je nachdem ist deine Frage nämlich komplex oder sehr komplex. Wenn ich mir deine Tabellen so ansehe, dann sieht es so aus, als ob du nur ein Board hast.
ja, ist ein board: www.aspbb.org
Dein Problem läßt sich ganz simpel dadurch lösen, dass du (was mir in deiner Datenstruktur auf den ersten Blick fehlt) ein Feld hinzufügst, in dem verzeichnet ist, auf welche andere Nachricht die jeweilige Antwort eine Nachricht ist.
Also zurZeit habe ich ja 2 verschiedene Tabellen dafür.
Eine Antwort (zu einem Thema) erkenne ich durch die Themen_ID, die in der Tabelle Antworten vorhanden ist)
Logischerweise haben Nachrichten, die ein neues Thema starten, dann keine Angabe in diesem Feld und können sehr leicht herausgefiltert werden (wenn du ein Board hast, reicht auch einfach ein simples Flag "ist neues Thema" vs. "ist Antwort").
Wie kriegst du denn derzeit alle Antworten entsprechend ihrer Aufreihung untereinander?
ich selektiere aus der antworten tabelle alle datensätze, die zu einem thema gehören
(select * from antworten where themen_Id = 1 order by antwort_datum)
Diese Vorgehensweise ist insofern auch besser, weil sie wesentlich performanter sein dürfte als irgendein JOIN. Das hilft dir zwar nicht beim Verstehen von INNER JOINs, aber es löst dein Problem. :)
- Sven Rautenberg
Vielen Dank für die antwort
Moin!
Wie kriegst du denn derzeit alle Antworten entsprechend ihrer Aufreihung untereinander?
ich selektiere aus der antworten tabelle alle datensätze, die zu einem thema gehören
(select * from antworten where themen_Id = 1 order by antwort_datum)
Ok, dann kriegst du die erste Nachricht zu einem Thema dann, wenn du die Nachricht mit dem niedrigsten Datum suchst.
Du hast allerdings das Problem, dass ein
SELECT user, min(datum) FROM tabelle GROUP BY user
dir zwar die Benutzer-ID und das kleinste Datum bringt, du aber nicht einfach weitere Postinginhalte hinzuselektieren kannst - GROUP BY wüßte nicht, welcher Eintrag zu wählen ist.
Deshalb ist es am sinnvollsten, wenn du dem ersten Eintrag einfach ein Flag hinzufügst. Nach dem kannst du suchen:
SELECT ... FROM tabelle WHERE flag="erster eintrag"
- Sven Rautenberg
Moin!
Wie kriegst du denn derzeit alle Antworten entsprechend ihrer Aufreihung untereinander?
ich selektiere aus der antworten tabelle alle datensätze, die zu einem thema gehören
(select * from antworten where themen_Id = 1 order by antwort_datum)Ok, dann kriegst du die erste Nachricht zu einem Thema dann, wenn du die Nachricht mit dem niedrigsten Datum suchst.
ok. aber ich glaub wir sind da vom ziel abgekommen.
Du hast allerdings das Problem, dass ein
SELECT user, min(datum) FROM tabelle GROUP BY user
dir zwar die Benutzer-ID und das kleinste Datum bringt, du aber nicht einfach weitere Postinginhalte hinzuselektieren kannst - GROUP BY wüßte nicht, welcher Eintrag zu wählen ist.
wow...hier hab ich gleich 2 sachen gesehen, die ich nicht kenne!
min(datum).... und group BY (wobei ich das by nicht verstehe)
sei mir nicht böse, wenn ich das alles frage..aber ich möchte alle funktionen optimal nutzen können, und bin über jede antwort froh, die mir irgendwie nutzen kann.
Nochmal zum ZIel.. weil ich glaube ich habe mich nicht verständlich ausgedrückt.
Standort: Board-Übersicht...
Angenommen, Forum: test
Ich habe in der Übersicht ein forum (das themen und antworten enthält), und möchte ausgeben, was zuletzt in diesem forum los war.
Wie finde ich am effektivsten raus, ob zuletzt ein datum erstellt worden ist, oder zuletzt eine antwort geschrieben worden ist.
Meine derzeitige Methode: ich hol mir das datum vom letzten them, und das datum von der letzten antwort. dann vergleiche ich diese
if datum_lastthema > datum_lastantwort then...
das problem ist aber: was, wenn die am gleichen tag geschrieben worden sind... dann müsste ich auch noch die uhrzeit vergleichen.
da gibt es doch bestimmt eine einfachere lösung.
Deshalb ist es am sinnvollsten, wenn du dem ersten Eintrag einfach ein Flag hinzufügst. Nach dem kannst du suchen:
SELECT ... FROM tabelle WHERE flag="erster eintrag"
das habe ich nicht ganz verstanden. warum ersten eintrag-flag. ich weiß doch eh was der erste eintrag ist. themen/antworten sind ja 2 verschiedene tabellen. oder meinst du bei den antworten...welche die erste antwort?
- Sven Rautenberg
ich verzweifel noch an diesem problem, bitte hilf mir, danke
Übeleis Markus
Moin!
Du hast allerdings das Problem, dass ein
SELECT user, min(datum) FROM tabelle GROUP BY user
dir zwar die Benutzer-ID und das kleinste Datum bringt, du aber nicht einfach weitere Postinginhalte hinzuselektieren kannst - GROUP BY wüßte nicht, welcher Eintrag zu wählen ist.wow...hier hab ich gleich 2 sachen gesehen, die ich nicht kenne!
min(datum).... und group BY (wobei ich das by nicht verstehe)sei mir nicht böse, wenn ich das alles frage..aber ich möchte alle funktionen optimal nutzen können, und bin über jede antwort froh, die mir irgendwie nutzen kann.
Die beiden Dinge hängen eng miteinander zusammen.
GROUP BY (als ein Befehl zu betrachten) gruppiert die danach angegebenen Spalten, d.h. identische Einträge ziehen die beteiligten Zeilen zu einer zusammen:
Wenn du ohne GROUP BY folgendes Ergebnis kriegst:
SELECT user_id, datum, text FROM tabelle
user_id datum text
3 20021201 irgendwas
3 20021204 irgendwas anderes
dann kannst du alle Postings von User-ID 3 zusammenfassen mit "GROUP BY user_id" und erhälst nur noch eine Zeile:
SELECT user_id FROM tabelle GROUP BY user_id
user_id
3
Das Problem ist: Du hast zwei Zeilen zusammengefaßt, die auch noch andere Felder enthalten. Wenn du die aber einfach mit ausgeben willst:
SELECT user_id, datum, text FROM tabelle GROUP BY user_id
dann hast du das Problem: Welcher Eintrag von den beiden in der Tabelle enthaltenen soll in der resultierenden Zeile enthalten sein?
Mit
SELECT user_id, min(datum) FROM tabelle GROUP BY user_id
erhälst du als Datumseintrag das niedrigste (früheste) Datum:
user_id min(datum)
3 20021201
Du kriegst aber leider das dazugehörige Textfeld nicht, weil auch der Text irgendwie mit einer sogenannten Aggregatsfunktion ausgewählt werden muß. MySQL nimmt zufällige Werte, wenn du es mit
SELECT user_id, min(datum), text FROM tabelle GROUP BY user_id
dennoch versuchst, andere Datenbanken geben einen Fehler zurück.
Angenommen, Forum: test
Ich habe in der Übersicht ein forum (das themen und antworten enthält), und möchte ausgeben, was zuletzt in diesem forum los war.Wie finde ich am effektivsten raus, ob zuletzt ein datum erstellt worden ist, oder zuletzt eine antwort geschrieben worden ist.
Meine derzeitige Methode: ich hol mir das datum vom letzten them, und das datum von der letzten antwort. dann vergleiche ich diese
if datum_lastthema > datum_lastantwort then...
Aha, deine Datenstruktur ist also für die zu lösende Aufgabe suboptimal. Ich würde in der Thementabelle nur solche Dinge wie Titel, Anfangsdatum etc. speichern, und in der Antwortentabelle auch schon gleich das erste Posting des Themas. Das erste Posting ist dann logischerweise die ursprüngliche Nachricht. Wenn zu deinem Thema nur eine Nachricht existiert, ist die aktuellste Nachricht logischerweise ein neues Thema - existieren mehr als eine Nachricht, ist die letzte Aktion eine Antwort gewesen.
SELECT count(datum), max(datum), thread_id FROM antwortentabelle GROUP BY thread_id
Das gibt dir einmal die Anzahl der Postings zurück, dann das Datum der letzten Änderung, und die thread_id. Und wenn du das Ausgangsposting nicht in der Antwortentabelle speicherst, hast du ein Problem: Wo nichts gespeichert ist, kann man nichts finden.
das problem ist aber: was, wenn die am gleichen tag geschrieben worden sind... dann müsste ich auch noch die uhrzeit vergleichen.
Es ist ohnehin schlau, einen ordentlichen Timestamp zu speichern, mit Datum und Uhrzeit bis hin zu Sekunden, evtl. auch Microsekunden. Dann kannst du eindeutig bestimmen, welches Posting das zeitlich letzte ist.
das habe ich nicht ganz verstanden. warum ersten eintrag-flag. ich weiß doch eh was der erste eintrag ist. themen/antworten sind ja 2 verschiedene tabellen. oder meinst du bei den antworten...welche die erste antwort?
Eine das Thema eröffnende Antwort ist kein spezielles Posting, so dass es nicht gerechtfertigt ist, diese in eine eigene Tabelle zu packen.
- Sven Rautenberg