Olli: Nahe am Wahnsinn: Aktive User pro Chatraum errechnen

Hallo,

ich bin seit Stunden auf der Suche nach einer Lösung und sehe langsam den Wald vor lauter Bäumen nicht mehr... Ich hoffe, mir kann jemand weiterhelfen.

Ich habe eine Datenbank mit Logfiles eines Chats und möchte daraus die Anzahl der innerhalb der letzten 10 Minuten aktiven User pro Raum erhalten.
Das Problem an der Sache ist, dass der/die User innerhalb des Zeitraums auch den Chatraum gewechselt haben und bei einer einfachen DISTINCT Abfrage den/die User doppelt habe.

Datenbank Beispiel:
user | raum | datum
1 | 1 | 2007-10-23 11:10:04
2 | 1 | 2007-10-23 11:10:24
5 | 1 | 2007-10-23 11:10:50
1 | 2 | 2007-10-23 11:11:10
1 | 3 | 2007-10-23 11:12:00
2 | 1 | 2007-10-23 11:12:08

Wie man sieht, hat User 1 erst in Raum 1 geschrieben, später dann in Raum 2 und 3.
Da ich die Anzahl der aktiven User pro Chatroom zählen möchte, darf ich daher nur das letzte Posting eines jeden Users mit einbeziehen (da der User ja sonst fälschlicherweise in den anderen Chatrooms, die er zuvor besucht hatte, auch als aktiver User mitgezählt wird).

Ich hatte unter Anderem auch versucht, mit MAX(datum) an das letzte Posting eines jeden Users zu kommen - allerdings wurden mir dann weiterhin irgendwelche, nicht zu dem MAX(datum) gehörenden Raum-Ids ausgegeben.

Optimal wäre etwas wie:
SELECT raum, COUNT(*) FROM chat WHERE datum>DATE_ADD(NOW(), INTERVAL -10 MINUTE) GROUP BY raum
Aber irgendwie will das nicht so wie ich will... :(

Ich hoffe, jemand von Euch hat eine Idee und kann mir weiterhelfen.
Tausend Dank für Eure Hilfe!!!

Viele Grüße

Olli

  1. Hallo

    user | raum | datum
    1 | 1 | 2007-10-23 11:10:04
    2 | 1 | 2007-10-23 11:10:24
    5 | 1 | 2007-10-23 11:10:50
    1 | 2 | 2007-10-23 11:11:10
    1 | 3 | 2007-10-23 11:12:00
    2 | 1 | 2007-10-23 11:12:08

    Wie man sieht, hat User 1 erst in Raum 1 geschrieben, später dann in Raum 2 und 3.
    Da ich die Anzahl der aktiven User pro Chatroom zählen möchte, darf ich daher nur das letzte Posting eines jeden Users mit einbeziehen (da der User ja sonst fälschlicherweise in den anderen Chatrooms, die er zuvor besucht hatte, auch als aktiver User mitgezählt wird).

    diese Zählweise verstehe ich zwar nicht, aber auch Dir sollten meine Ausführungen zu korrelierten Unterabfragen weiterhelfen.

    Freundliche Grüße

    Vinzenz

    1. diese Zählweise verstehe ich zwar nicht, aber auch Dir sollten meine Ausführungen zu korrelierten Unterabfragen weiterhelfen.

      Das Listing sollte einfach einen Auszug aus den Datensätzen sein.
      Als Ergebnis möchte ich folgendes haben:
      raum | anzahl aktiver chatter
      1 | 2
      2 | 0
      3 | 1

      User 1 soll also nur in die Zählung des Raumes 3 einfliessen, da sein letztes Posting eben in Raum 3 getätigt wurde - und nicht in Raum 2 oder 1.

      Deine Ausführungen zu Unterabfragen sind sehr Interessant, vielen Dank für den Hinweis. Da sie erst ab Version 4 funktionieren, habe ich kurzerhand einen Versionswechsel der DB vorgenommen. Ich werds mal ausprobieren, vielen Dank!

      Viele Grüße

      Olli

  2. yo,

    welches dbms und welche version ?

    Ilja

    1. Ich habe MySQL 3.23.58! Wenns was hilft, könnte ich auch auf 4.1.22 wechseln.

      1. yo,

        Ich habe MySQL 3.23.58! Wenns was hilft, könnte ich auch auf 4.1.22 wechseln.

        der wechsel ist anzuraten, womit du auch unterabfragen ausführen kannst. Wie Vinz schon ansprach, sind korrelierte unterabfragen eine sehr schöne lösung. Ich gebe sie dir mal vor, falls du nicht selbst schon darauf gekommen bist. die korrelation passiert in der unterabfrage in der where klausel.

        SELECT t1.raum, COUNT(*) Anzahl
        FROM chat t1
        WHERE t1.datum = (SELECT MAX(t2.datum)
                          FROM chat t2
                          WHERE t2.user = t1.user
                         )
        GROUP BY t1.raum
        ;

        Ilja

        1. SUPER SUPER SUPER :)

          Genau das ist es!!!
          Diese Abfrage hab ich mir gerade exakt so zusammengefriemelt und wollte sie hier reinstellen, damit ihr mal rüberschauen könnt. Hat sich aber dank deines schnellen Postings schon von selbst erledigt. Hab vielen Dank!
          Dann kann es ja jetzt endlich weitergehen :)

          Viele Grüsse

          Olli

          1. Oha... Ich habs gestern probiert und es hat funktioniert...
            Heute mache ich die selbe Abfrage und es passiert ... nichts!
            MySQL liefert kein Ergebnis?!

            Hier die komplette Abfrage:
            SELECT c1.room, COUNT(*) FROM chat AS c1 WHERE c1.datum=(SELECT MAX(c2.datum) FROM chat AS c2 WHERE c2.user=c1.user GROUP BY c2.user HAVING MAX(c2.datum) > DATE_ADD(NOW(), INTERVAL -10 MINUTE)) GROUP BY c1.room

            In der Datenbank sind entsprechende Datensätze vorhanden!
            Verzichte ich auf das COUNT(*) und das GROUP BY c1.room - und lasse mir stattdessen die Datensätze anzeigen, klappt es problemlos:
            SELECT c1.room, c1.user FROM chat AS c1 WHERE c1.datum=(SELECT MAX(c2.datum) FROM chat AS c2 WHERE c2.user=c1.user GROUP BY c2.user HAVING MAX(c2.datum) > DATE_ADD(NOW(), INTERVAL -1000 MINUTE))

            Was kann das sein? Denkfehler meinerseits?
            Habt vielen Dank für Euren Denkanstoss!

            Viele Grüße

            Olli

            1. Nachtrag: Ich habe mir gedacht "wenn schon, denn schon" und gleich nochmal auf MySQL 5.0.41 upgedated.
              Wenn ich aber die alte MySQl 4.1.22 DB verwende, klappt es anstandslos - mit identischen Daten und Abfragen!

              Kann MySQL 5 derartige Abfragen nicht? Bringt es dann überhaupt einen Vorteil, auf V5 umzuziehen (Performance o.ä.)?

              1. yo,

                Kann MySQL 5 derartige Abfragen nicht? Bringt es dann überhaupt einen Vorteil, auf V5 umzuziehen (Performance o.ä.)?

                jede umstellung auf eine neue version kann kritisch sein. alerdings liegt es weniger der funktionalität der 5er version, die kann auch unterabfragen und natürlich auch gruppieren.

                Es könnte eventuell an den aliasnamen liegen, das ist aber eine vermutung ins blaue hinein. mach mal den aliasnamen der tabelle ohne das "AS".

                Ilja