OK,我知道我有點晚了,但我想反正張貼我的答案:-)
你需要什麼可以使用子查詢來完成,但是這可能需要年齡完成對大表...
思考這個問題我來到兩種不同的方法。
其中一個問題已經在其他答案中處理過了,它在特定時間點開始工作,查看此時開始的時間間隔,然後查看緊接着的相同時間間隔。這導致清晰,可理解的結果,並且可能是需要的(例如,每個日曆日用戶不得超過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-2015之間的無限多01-25 23:59:59'。但是,隨着服務器的精度爲1秒,這歸結爲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)
如果該查詢接受一個時間戳「時期的開始」,計算「期末」,並列出誰超過了在此期間的下載量所有用戶,還是應該列出每24小時超過x次下載量的所有用戶? –
@Patrick沒有開始也沒有結束期...只列出誰超過在Y的X下載(因爲這可能是一個時間從24小時不同時間段)的時間限制 – eduardev
我在想一個(可能的)解決方案的所有用戶。如果您仍然對此感興趣,我會解決它,並將其發佈到此處,但這會帶來負面影響:想象一下,我只在一小時內完成100次下載,然後會有很多時間段超出限制。例如:今天上午8點到9點之間下載100次。昨天上午9點至今天上午9點=下載100次。昨天上午10點直到今天上午10點=下載100次。昨天上午11點至今天上午11點=下載100次。待續... –