devian01: Brauche Hilfe: Komplizierte MYSQL-Abfrage

Hallo Liebe Community,
ich arbeite seit ungelogen 3-4 Stunden daran eine Abfrage zu schreiben, die mir einfach nicht gelingen will. Ich hoffe ihr könnt mir helfen.

Ich habe zwei Tabellen. In der einen sind die Themen eingetragen und in der anderen die Beiträge zu diesen Themen. Beide Tabellen haben die themenid  gemeinsam. In der Tabelle der Beiträge sind ganz viele Beiträge von Usern meiner Seite. Ich will nun die Themen in die ein bestimmter User geschrieben hat, nach dem Datum sortieren andem er die Beiträge geschrieben hat.Die Themen sollen aber nicht doppelt aufgelistet werden.

Hier mal die Tabellen zur veranschaulichung:

Tabellenname: Themen

themenid    themenname
   1          thema1
   2          thema2
   3          thema3

__________________________________

Tabellenname: Beiträge

themenid     beitragsis    userid         posttime
    1            13           1         (timestamp_vorgestern)
    3            14           3         (timestamp_gestern)
    4            14           1         (timestamp_vor3stunden)
    1            15           1         (timestamp_vor3minuten)
    1            16           2         (timestamp_voreinemJahr)
    5            17           1         (timestamp_vor3sekunden)
    5            18           1         (timestamp_vor5jahren)

Ich will nun die Themen vom User mit der ID 1 nach ihrer aktualität auflisten lassen. Das Problem ist, dass die ids der Themen zum Teil Doppelt sind. Ich will die Themen aber nicht doppelt auflisten, sondern nur einmal.
In dem Beispiel also, sollte es nachher so aussehen:

themenid          userid           posttime
   5                 1          (timestamp_vor3sekunden)
   1                 1          (timestamp_vor3minuten)
   4                 1          (timestamp_vor3stunden)

Aber die Themenid's sollen nicht doppelt sein. So wie hier:

themenid          userid           posttime
   5                 1          (timestamp_vor3sekunden)
   1                 1          (timestamp_vor3minuten)
   4                 1          (timestamp_vor3stunden)
   1                 1          (timestamp_vorgestern)
   5                 1          (timestamp_vor5jahren)

Mein Ansatz lieferte mir bisher immer nur das ungewünschte Ergebniss:

SELECT t.themenid
FROM Beiträge
WHERE userid ='1'
ORDER BY posttime DESC

Ich habe es mit GROUP BY oder DISTINCT versucht, aber jedes mal, wenn ich es so mache werden die Themen nichtmehr nach posttime sortiert.

Ich hoffe ihr versteht mein Problem und könnt mir weiterhelfen.

  1. Lieber devian01,

    WHERE userid ='1'

    ist "userid" wirklich vom Typ CHAR?

    SELECT t.themenid
    FROM Beiträge
    WHERE userid ='1'
    ORDER BY posttime DESC

    Und was ist mit "SELECT DISTINCT t.themenid FROM Beiträge WHERE userid='1' ORDER BY posttime DESC"?

    Liebe Grüße,

    Felix Riesterer.

    --
    ie:% br:> fl:| va:) ls:[ fo:) rl:° n4:? de:> ss:| ch:? js:) mo:} zu:)
  2. Ich will die Themen aber nicht doppelt auflisten, sondern nur einmal.

    Welches Beitragsdatum soll dann erscheinen?
    Deine bisherige Abfrage holt alle ThemenIDs zu den Beiträgen, also mehrere.
    GROUP BY wär schon richtig, damit kriegst du jedes Thema nur einmalig. Dadnn bleibt allerdings die Frage, welches Datum du ausgegeben haben willst. Dein Beispiel sieht nach MAX(datum) aus, nämlich immer das letzte?

    PS: SQL wär passender gewesen als PHP

  3. Hallo,

    Ich will nun die Themen in die ein bestimmter User geschrieben hat, nach dem Datum sortieren andem er die Beiträge geschrieben hat.Die Themen sollen aber nicht doppelt aufgelistet werden.

    Tabellenname: Themen

    themenid    themenname
       1          thema1
       2          thema2
       3          thema3

    Tabellenname: Beiträge
    themenid     beitragsis    userid         posttime
        1            13           1         (timestamp_vorgestern)
        3            14           3         (timestamp_gestern)
        4            14           1         (timestamp_vor3stunden)
        1            15           1         (timestamp_vor3minuten)
        1            16           2         (timestamp_voreinemJahr)
        5            17           1         (timestamp_vor3sekunden)
        5            18           1         (timestamp_vor5jahren)

    Ich will nun die Themen vom User mit der ID 1 nach ihrer aktualität auflisten lassen. Das Problem ist, dass die ids der Themen zum Teil Doppelt sind. Ich will die Themen aber nicht doppelt auflisten, sondern nur einmal.

    themenid          userid           posttime
       5                 1          (timestamp_vor3sekunden)
       1                 1          (timestamp_vor3minuten)
       4                 1          (timestamp_vor3stunden)

    Ich hoffe ihr versteht mein Problem und könnt mir weiterhelfen.

    Du suchst die korrelierte Unterabfrage. Du solltest mein Minitutorial auf Dein Problem anwenden können.

    Freundliche Grüße

    Vinzenz

  4. moin,

    ich arbeite seit ungelogen 3-4 Stunden daran eine Abfrage zu schreiben, die mir einfach nicht gelingen will.

    Vinzenz hat dir schon den richtigen hinweis gegeben, ich will ihn noch ein wenig ergänzen. ein motto von mir ist: "joins sind böse". natürlich sind sie das nicht wirklich, aber man sollte das motto verinnerlichen. der grund dafür ist, dass man oftmals nur eine bestimmte anzahl an datensätze in der ergebnismenge haben will (meistens aus einer tabelle wie bei dir die themen), aber in andere tabellen notwende informationen dazu stehen. dann joint man diese und bekommt meistens dann eine andere anzahl von datensätze zurück.

    deshalb verfolge ich einen anderen ansatz, ich suche mir als ertes die basis der datensätze, die ich zurück haben will, also bei dir die themen tabelle, die du dann über den timestamp sortieren kannst.

    SELECT *
    FROM Themen
    ORDER BY posttime
    ;

    nun stimmt schon mal deine ergebnismenge und sind auch schon fast am ziel. wir müssen nur noch die themen selektieren, wo der user mit der id = 1 auch beträge geschrieben hat. und das macht man am besten mit der von Vinzen angesprochenen korrelierten unterabfrage in verbindung mit einem schönen operator EXITS.

    SELECT *
    FROM Themen t
    WHERE EXISTS (SELECT NULL
                  FROM beiträge b -- du solltest das ä im tabellennamen vermeiden
                  WHERE b.themenid = t.themenid -- hier ist die korrelation
                  AND b.userid = 1
                 )
    ORDER BY posttime
    ;

    und das sollte alles sein.

    Ilja