Mysql
 sql >> база данни >  >> RDS >> Mysql

mysql изберете броя на редовете между интервала от време

Добре, разбирам, че закъснях малко, но все пак исках да публикувам отговора си :-)

Това, от което се нуждаете, може да бъде направено с помощта на подзаявка, но това може да отнеме години, за да се завърши на голяма таблица...

Мислейки по въпроса, стигнах до два различни подхода.

Един от тях вече е разгледан в другите отговори, той работи, като се започне в определен момент от време, гледа се интервалът, който започва в този момент и след това се разглежда интервалът с еднаква продължителност, който непосредствено следва. Това води до ясни, разбираеми резултати и вероятно е това, което би било необходимо (например потребителят не трябва да надвишава 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)


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Създаване на променлива на масив в MySQL

  2. mySQL:utf8 charset в индексната таблица и грешка при дублиран ключ

  3. Грешка с MySql, докато правите Bundle Install

  4. въведените данни от формуляр не се записват в mysql db?

  5. Как да вмъкна нов ред в базата данни с колона AUTO_INCREMENT, без да указвате имена на колони?