NBG: GROUP BY + ORDER BY

Hallo,

ich möchte die Profilbesucher auflisten lassen.

Dabei sollen die letzten Besucher oben stehen und jeder nur maximal einmal (Mehrfachbesuche werden also von den Usern nicht angezeigt, immer nur der letzte).

SELECT

*

FROM

profilbesucher

WHERE

besuch_bei=1

GROUP BY

besuch_von

ORDER BY

besuch_zeit

DESC

Das funktioniert soweit, nur zeigt er mir beim ersten User oben z.B. eine Zeit an, wo er zwar auf dem Profil war, allerdings gibt es in der Tabelle schon einen wesentlich neueren Besuch von ihm...

Woran kann das liegen?

  1. Hi,

    lass mich raten:

    DBMS: Mysql

    besuch_von: User-ID

    besuch_zeit: timestamp

    Tja, das geht so leider nicht. Mit 'GROUP BY' werden die Daten verdichtet, d.h. pro Instanz von 'besuch_von' gibt es genau ein Ruechkabetupel.

    Bedauerlicherweise wird das ORDER BY (zumindest vermute ich das mal) erst am Ende ausgefuehrt.

    Im uebrigen, *-Selekor, vorallem mit GROUP BY is immer schlecht. Ich denke der Code funktioniert eh nur mit MySQL (bei Interesse kannst da mal nachforschen).

    SELECT max(besuch_zeit) AS last_logon_time, besuch_bei
    FROM profilbesucher
    WHERE besuch_bei = 1
    GROUP BY besuch_bei
    [ORDER BY last_logon_time DESC]

    Bitte selber testen ob das ORDER BY funktioniert, bin mir da garnicht sicher. Auch weiss ich nicht 100% ob der Call ueberhaupt geht, kann das hier nicht testen.

    Wenn nicht, dann das evtl. in eine Unterabfrage packen (wiederum, selber testen)

    SELECT * FROM
    (
            SELECT max(besuch_zeit) AS last_logon_time, besuch_bei
            FROM profilbesucher
            WHERE besuch_bei = 1
            GROUP BY besuch_bei
    )
    AS tmp_table ORDER BY last_logon_time DESC

    Hope this helps!

  2. Hallo

    Dabei sollen die letzten Besucher oben stehen und jeder nur maximal einmal (Mehrfachbesuche werden also von den Usern nicht angezeigt, immer nur der letzte).

    SELECT
    *
    FROM
    profilbesucher
    WHERE
    besuch_bei=1
    GROUP BY
    besuch_von
    ORDER BY
    besuch_zeit
    DESC

    Das funktioniert soweit,

    nur zeigt er mir beim ersten User oben z.B. eine Zeit an, wo er zwar auf dem Profil war, allerdings gibt es in der Tabelle schon einen wesentlich neueren Besuch von ihm...

    Woran kann das liegen?

    daran, dass Du MySQL verwendest.

    Jedes andere mir bekannte Datenbankmanagementsystem (DBMS) weist Deine Abfrage
    als mit einer Fehlermeldung zurück. Wenn Du die GROUP-BY-Klausel verwendest,
    musst Du nach _jeder_ Spalte, auf die keine Aggregatsfunktion angewandt wird,
    gruppieren. Daraus ergibt sich von selbst, dass Du im Normalfall nicht

    SELECT *

    verwenden kannst, weil Du dann ja eh' alle Spalten in der GROUP-BY-Klausel
    aufführen musst.

    Bist Du nur am Namen des Besuchers und seiner Besuchzeit interessiert, so
    kommst Du mit einer einfachen Abfrage hin:

    SELECT  
        besucher,  
        MAX(besuch_zeit),  
    FROM profilbesucher  
    WHERE besuch_bei = 1  
    GROUP BY besucher  
    ORDER BY MAX(besuch_zeit) DESC
    

    siehe auch SELFHTML aktuell, Artikel Datensätze gruppieren mit SQL

    Wenn Du noch weitere Informationen haben möchtest, die sich nicht durch eine
    Aggregatsfunktion ermitteln lassen, dann ist eine korrelierte Unterabfrage das
    Mittel der Wahl, siehe dazu dieses Archivposting von mir.

    Freundliche Grüße

    Vinzenz