Oke, saya sadar saya agak terlambat, tetapi saya tetap ingin memposting jawaban saya :-)
Apa yang Anda butuhkan dapat dilakukan dengan menggunakan subkueri, tetapi ini mungkin membutuhkan waktu lama untuk diselesaikan pada tabel besar...
Memikirkan pertanyaan itu, saya sampai pada dua pendekatan berbeda.
Salah satunya telah dibahas dalam jawaban lain, ia bekerja dengan memulai pada titik waktu tertentu, melihat interval yang dimulai saat ini dan kemudian melihat interval durasi yang sama yang segera mengikuti. Ini mengarah pada hasil yang jelas dan dapat dimengerti dan mungkin itulah yang diperlukan (misalnya, pengguna tidak boleh melebihi 100 unduhan per hari kalender). Namun ini sama sekali akan melewatkan situasi di mana pengguna melakukan 99 unduhan selama satu jam sebelum tengah malam dan 99 lainnya pada jam pertama hari baru.
Jadi jika hasil yang diperlukan lebih dari "daftar sepuluh pengunduh teratas", maka ini adalah pendekatan lain. Hasil di sini mungkin tidak dapat dimengerti pada pandangan pertama, karena satu unduhan dapat dihitung dalam beberapa interval. Ini karena interval akan (dan perlu) tumpang tindih.
Berikut pengaturan saya. Saya telah membuat tabel dari pernyataan Anda dan menambahkan dua indeks:
CREATE INDEX downloads_timestamp on downloads (dl_date);
CREATE INDEX downloads_user_id on downloads (user_id);
Data yang saya masukkan ke dalam tabel:
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)
Seperti yang Anda lihat, semua unduhan terjadi kemarin atau hari ini dan dijalankan oleh dua pengguna yang berbeda.
Sekarang, yang harus kita pikirkan adalah sebagai berikut:Ada (secara matematis) interval 24 jam yang tak terbatas (atau interval durasi lainnya) antara '2011-01-24 0:00' dan '2011-01-25 23 :59:59'. Tetapi karena presisi server hanya satu detik, ini bermuara pada 86.400 interval:
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
Jadi kita bisa menggunakan loop untuk mengulangi semua interval ini dan menghitung jumlah unduhan per pengguna dan per interval. Tentu saja, tidak semua interval memiliki minat yang sama bagi kita, jadi kita dapat melewatkan beberapa di antaranya dengan menggunakan stempel waktu dalam tabel sebagai "awal interval".
Inilah yang dilakukan kueri berikut. Ini menggunakan setiap stempel waktu unduhan dalam tabel sebagai "awal interval", menambahkan durasi interval dan kemudian menanyakan jumlah unduhan per pengguna selama interval ini.
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;
Ini hasilnya:
+---------+---------------------+---------------------+-------+
| 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)