Группировка по диапазону X дней - PullRequest
5 голосов
/ 20 января 2011

У меня есть набор или записи, и я хочу посчитать и сгруппировать их по определенному диапазону, например, я хочу подсчитать записи, которые были созданы группами по X дней

e.g. SELECT COUNT(*) FROM `table` GROUP BY /*`created` 3 days/*

Ответы [ 3 ]

6 голосов
/ 21 января 2011

Вот пример с датами.

create table t1(created date not null);

insert 
  into t1(created) values (date '2011-01-09')
                         ,(date '2011-01-10')
                         ,(date '2011-01-11')
                         ,(date '2011-01-12')
                         ,(date '2011-01-13')
                         ,(date '2011-01-14')
                         ,(date '2011-01-15')
                         ,(date '2011-01-16')
                         ,(date '2011-01-17')
                         ,(date '2011-01-18')
                         ,(date '2011-01-19')
                         ,(date '2011-01-20');

select floor(datediff(now(), created) / 3) * 3 as days_ago
      ,min(created)
      ,max(created)
      ,count(*)
  from t1
 group 
    by floor(datediff(now(), created) / 3);

+----------+--------------+--------------+----------+
| days_ago | min(created) | max(created) | count(*) |
+----------+--------------+--------------+----------+
|        0 | 2011-01-18   | 2011-01-20   |        3 |
|        3 | 2011-01-15   | 2011-01-17   |        3 |
|        6 | 2011-01-12   | 2011-01-14   |        3 |
|        9 | 2011-01-09   | 2011-01-11   |        3 |
+----------+--------------+--------------+----------+
4 rows in set (0.00 sec)
3 голосов
/ 20 января 2011

Вы можете сделать что-то вроде
SELECT COUNT(*) FROM table GROUP BY FLOOR(created / 3)

... я думаю.

Хотя, если created - это поле даты, вам придется немного поиграть, чтобы получить числовое значение, чтобы это работало.

1 голос
/ 30 июня 2016

Спасибо @Ronnis, я использую твой пример и наконец решаю свою проблему.

И я обнаружил небольшую ошибку, например, я добавляю одну строку

insert into t1(created) values (date '2011-01-21')

Теперь яget:

+----------+--------------+--------------+----------+
| days_ago | min(created) | max(created) | count(*) |
+----------+--------------+--------------+----------+
|     1986 | 2011-01-20   | 2011-01-21   |        2 |
|     1989 | 2011-01-17   | 2011-01-19   |        3 |
|     1992 | 2011-01-14   | 2011-01-16   |        3 |
|     1995 | 2011-01-11   | 2011-01-13   |        3 |
|     1998 | 2011-01-09   | 2011-01-10   |        2 |
+----------+--------------+--------------+----------+

Как видите, дни делятся на 2, 3, 3, 3, 2, что не соответствует ожиданиям.

Я изменяю SQL как

select floor(datediff(created, '2011-01-09') / 3) * 3 as days_before
      ,min(created)
      ,max(created)
      ,count(*)
from t1
group by floor(datediff(created, '2011-01-09') / 3);

Просто получите дату от созданного до даты начала, и теперь я получаю:

+-------------+--------------+--------------+----------+
| days_before | min(created) | max(created) | count(*) |
+-------------+--------------+--------------+----------+
|           0 | 2011-01-09   | 2011-01-11   |        3 |
|           3 | 2011-01-12   | 2011-01-14   |        3 |
|           6 | 2011-01-15   | 2011-01-17   |        3 |
|           9 | 2011-01-18   | 2011-01-20   |        3 |
|          12 | 2011-01-21   | 2011-01-21   |        1 |
+-------------+--------------+--------------+----------+

Это может быть более подходящим.

...