Добре, разбирам, че закъснях малко, но все пак исках да публикувам отговора си :-)
Това, от което се нуждаете, може да бъде направено с помощта на подзаявка, но това може да отнеме години, за да се завърши на голяма таблица...
Мислейки по въпроса, стигнах до два различни подхода.
Един от тях вече е разгледан в другите отговори, той работи, като се започне в определен момент от време, гледа се интервалът, който започва в този момент и след това се разглежда интервалът с еднаква продължителност, който непосредствено следва. Това води до ясни, разбираеми резултати и вероятно е това, което би било необходимо (например потребителят не трябва да надвишава 100 изтегляния на календарен ден). Това обаче напълно би пропуснало ситуации, в които потребителят прави 99 изтегляния през часа преди полунощ и още 99 през първия час на новия ден.
Така че, ако желаният резултат е по-скоро „списък с десетте най-добри изтеглящи“, тогава това е другият подход. Резултатите тук може да не са толкова разбираеми на пръв поглед, тъй като едно изтегляне може да се брои на множество интервали. Това е така, защото интервалите ще (и трябва) да се припокриват.
Ето моята настройка. Създадох таблицата от вашето изявление и добавих два индекса:
CREATE INDEX downloads_timestamp on downloads (dl_date);
CREATE INDEX downloads_user_id on downloads (user_id);
Данните, които вмъкнах в таблицата:
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)
Както можете да видите, всички изтегляния са се случили вчера или днес и са били изпълнени от двама различни потребители.
Сега, това, което трябва да имаме предвид е следното:Има (математически) безкраен брой 24-часови интервали (или интервали с всякаква друга продължителност) между „2011-01-24 0:00“ и „2011-01-25 23 :59:59'. Но тъй като точността на сървъра е една секунда, това се свежда до 86 400 интервала:
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
Така че можем да използваме цикъл, за да повторим през всички тези интервали и да изчислим броя на изтеглянията на потребител и на интервал. Разбира се, не всички интервали представляват еднакъв интерес за нас, така че можем да пропуснем някои от тях, като използваме времевите марки в таблицата като „начало на интервала“.
Това прави следната заявка. Той използва всяко клеймо за дата на изтегляне в таблицата като „начало на интервала“, добавя продължителността на интервала и след това прави заявка за броя изтегляния на потребител през този интервал.
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;
Ето резултата:
+---------+---------------------+---------------------+-------+
| 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)