Übeleis Markus: inner join bis heute nicht begriffen

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

  1. 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

    --
    Diese Signatur gilt nur am Freitag.
    1. 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

      1. 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

        --
        Diese Signatur gilt nur am Freitag.
        1. 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

          1. 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

            --
            Diese Signatur gilt nur am Freitag.