Mysql
 sql >> Datenbank >  >> RDS >> Mysql

mysql select Anzahl der Zeilen zwischen Zeitspanne

OK, ich merke, dass ich ein bisschen spät bin, aber ich wollte meine Antwort trotzdem posten :-)

Was Sie benötigen, kann mit einer Unterabfrage erledigt werden, aber das kann bei einer großen Tabelle Ewigkeiten dauern...

Als ich über die Frage nachdachte, stieß ich auf zwei verschiedene Ansätze.

Eines davon wurde bereits in den anderen Antworten behandelt, es funktioniert, indem man zu einem bestimmten Zeitpunkt beginnt, das Intervall betrachtet, das zu diesem Zeitpunkt beginnt, und dann das Intervall gleicher Dauer betrachtet, das unmittelbar darauf folgt. Dies führt zu eindeutigen, nachvollziehbaren Ergebnissen und wäre wahrscheinlich auch erforderlich (z. B. darf der Nutzer 100 Downloads pro Kalendertag nicht überschreiten). Dies würde jedoch Situationen vollständig übersehen, in denen ein Benutzer 99 Downloads in der Stunde vor Mitternacht und weitere 99 in der ersten Stunde des neuen Tages durchführt.

Wenn das gewünschte Ergebnis also eher eine „Top-Ten-Downloader-Liste“ ist, dann ist dies der andere Ansatz. Die Ergebnisse hier sind auf den ersten Blick möglicherweise nicht so nachvollziehbar, da ein einzelner Download auf mehrere Intervalle angerechnet werden kann. Dies liegt daran, dass sich die Intervalle überschneiden (und müssen).

Hier ist mein Setup. Ich habe die Tabelle aus Ihrer Anweisung erstellt und zwei Indizes hinzugefügt:

CREATE INDEX downloads_timestamp on downloads (dl_date);
CREATE INDEX downloads_user_id on downloads (user_id);

Die Daten, die ich in die Tabelle eingefügt habe:

SELECT * FROM downloads;
+----+----------+---------+---------------------+
| id | stuff_id | user_id | dl_date             |
+----+----------+---------+---------------------+
|  1 |        1 |       1 | 2011-01-24 09:00:00 |
|  2 |        1 |       1 | 2011-01-24 09:30:00 |
|  3 |        1 |       1 | 2011-01-24 09:35:00 |
|  4 |        1 |       1 | 2011-01-24 10:00:00 |
|  5 |        1 |       1 | 2011-01-24 11:00:00 |
|  6 |        1 |       1 | 2011-01-24 11:15:00 |
|  7 |        1 |       1 | 2011-01-25 09:15:00 |
|  8 |        1 |       1 | 2011-01-25 09:30:00 |
|  9 |        1 |       1 | 2011-01-25 09:45:00 |
| 10 |        1 |       2 | 2011-01-24 08:00:00 |
| 11 |        1 |       2 | 2011-01-24 12:00:00 |
| 12 |        1 |       2 | 2011-01-24 12:01:00 |
| 13 |        1 |       2 | 2011-01-24 12:02:00 |
| 14 |        1 |       2 | 2011-01-24 12:03:00 |
| 15 |        1 |       2 | 2011-01-24 12:00:00 |
| 16 |        1 |       2 | 2011-01-24 12:04:00 |
| 17 |        1 |       2 | 2011-01-24 12:05:00 |
| 18 |        1 |       2 | 2011-01-24 12:06:00 |
| 19 |        1 |       2 | 2011-01-24 12:07:00 |
| 20 |        1 |       2 | 2011-01-24 12:08:00 |
| 21 |        1 |       2 | 2011-01-24 12:09:00 |
| 22 |        1 |       2 | 2011-01-24 12:10:00 |
| 23 |        1 |       2 | 2011-01-25 14:00:00 |
| 24 |        1 |       2 | 2011-01-25 14:12:00 |
| 25 |        1 |       2 | 2011-01-25 14:25:00 |
+----+----------+---------+---------------------+
25 rows in set (0.00 sec)

Wie Sie sehen können, erfolgten alle Downloads entweder gestern oder heute und wurden von zwei verschiedenen Benutzern ausgeführt.

Nun müssen wir uns Folgendes merken:Es gibt (mathematisch) unendlich viele 24-Stunden-Intervalle (oder Intervalle jeder anderen Dauer) zwischen '2011-01-24 0:00' und '2011-01-25 23' :59:59'. Aber da die Genauigkeit des Servers eine Sekunde beträgt, läuft dies auf 86.400 Intervalle hinaus:

First interval:  2011-01-24 0:00:00 -> 2011-01-25 0:00:00
Second interval: 2011-01-24 0:00:01 -> 2011-01-25 0:00:01
Third interval: 2011-01-24 0:00:02 -> 2011-01-25 0:00:02
   .
   .
   .
86400th interval: 2011-01-24 23:59:59 -> 2011-01-25 23:59:59

Wir könnten also eine Schleife verwenden, um alle diese Intervalle zu durchlaufen und die Anzahl der Downloads pro Benutzer und pro Intervall zu berechnen. Natürlich sind nicht alle Intervalle für uns gleich interessant, daher können wir einige davon überspringen, indem wir die Zeitstempel in der Tabelle als "Beginn des Intervalls" verwenden.

Dies ist, was die folgende Abfrage tut. Es verwendet jeden Download-Zeitstempel in der Tabelle als "Beginn des Intervalls", fügt die Intervalldauer hinzu und fragt dann die Anzahl der Downloads pro Benutzer in diesem Intervall ab.

SET @duration = '24:00:00';
SET @limit = 5;
SELECT * FROM 
    (SELECT t1.user_id, 
            t1.dl_date startOfPeriod, 
            ADDTIME(t1.dl_date,@duration) endOfPeriod, 
           (SELECT COUNT(1) 
            FROM downloads t2 
            WHERE t1.user_id = t2.user_id 
            AND t1.dl_date <= t2.dl_date 
            AND ADDTIME(t1.dl_date,@duration) >= t2.dl_date) count
     FROM downloads t1) t3 
WHERE count > @limit;

Hier ist das Ergebnis:

+---------+---------------------+---------------------+-------+
| user_id | startOfPeriod       | endOfPeriod         | count |
+---------+---------------------+---------------------+-------+
|       1 | 2011-01-24 09:00:00 | 2011-01-25 09:00:00 |     6 |
|       1 | 2011-01-24 09:30:00 | 2011-01-25 09:30:00 |     7 |
|       1 | 2011-01-24 09:35:00 | 2011-01-25 09:35:00 |     6 |
|       1 | 2011-01-24 10:00:00 | 2011-01-25 10:00:00 |     6 |
|       2 | 2011-01-24 08:00:00 | 2011-01-25 08:00:00 |    13 |
|       2 | 2011-01-24 12:00:00 | 2011-01-25 12:00:00 |    12 |
|       2 | 2011-01-24 12:01:00 | 2011-01-25 12:01:00 |    10 |
|       2 | 2011-01-24 12:02:00 | 2011-01-25 12:02:00 |     9 |
|       2 | 2011-01-24 12:03:00 | 2011-01-25 12:03:00 |     8 |
|       2 | 2011-01-24 12:00:00 | 2011-01-25 12:00:00 |    12 |
|       2 | 2011-01-24 12:04:00 | 2011-01-25 12:04:00 |     7 |
|       2 | 2011-01-24 12:05:00 | 2011-01-25 12:05:00 |     6 |
+---------+---------------------+---------------------+-------+
12 rows in set (0.00 sec)