从特定日期时间开始按日期时间段分组MYSQL行

时间:2015-11-13 16:02:50

标签: mysql sql group-by

我们说我有几个列,其中一个列的日期时间如下:

2015-07-19 17:00:01
2015-07-19 17:15:01
2015-07-19 17:30:01
2015-07-19 17:45:01
2015-07-19 18:00:01
2015-07-19 18:15:01
2015-07-19 18:30:01
2015-07-19 18:45:01
2015-07-19 19:00:01
2015-07-19 19:15:01
2015-07-19 19:30:01
2015-07-19 19:45:01
2015-07-19 20:00:01
2015-07-19 20:15:01

我希望输出每3小时循环一次以进行聚合:

2015-07-19 17:00:01, max(column B), etc
2015-07-19 20:00:01, max(column B), etc
2015-07-19 23:00:01, max(column B), etc
2015-07-20 02:00:01, max(column B), etc

我的尝试:

SELECT
datetime_col,
min(col_b)
FROM table
where datetime_col >= STR_TO_DATE('2015-07-19 17:00:01','%Y-%m-%d %H:%i:%s')
GROUP BY
YEAR(datetime_col),
MONTH(datetime_col),
DAY(datetime_col),
ROUND(HOUR(datetime_col)/3);

实际输出:

2015-07-19 17:00:01
2015-07-19 20:00:01
2015-07-19 23:00:01
2015-07-20 00:00:01
2015-07-20 02:00:01

您可以看到,首先分组看起来很好,直到它到达新的一天。无论日,月,年等,我都需要在3小时的周期内进行分组。

我希望在单个查询中执行此操作,因为我在C#应用程序中调用它;

3 个答案:

答案 0 :(得分:0)

简单的方法是创建一个包含日期和小时范围的表格。

以下是一天的示例,您需要按小时展开。

generate days from date range

所以你将拥有hour_block

id   startTime            endTime
 1   2015-07-19 00:00:01  2015-07-19 03:00:00
 2   2015-07-19 03:00:01  2015-07-19 06:00:00
 3   2015-07-19 06:00:01  2015-07-19 09:00:00
 ...         ...                ...
 8   2015-07-19 21:00:01  2015-07-20 00:00:00

然后你创建一个连接

 SELECT H.id, H.startTime, max(Y.column B)
 From YourTable Y
 JOIN hour_block H
   ON Y.datetime_col between H.startTime and H.endTime
 GROUP BY H.id, H.startTime

答案 1 :(得分:0)

我会通过将值转换为最接近的前3小时来处理此问题。使用to_seconds()这很容易,但不允许转换回来。所以:

SELECT FROM_UNIXTIME(FLOOR(UNIX_TIMESTAMP(datetimecol) / (60 * 60 / 3) )) as datetime,
      min(col_b)
FROM table
WHERE datetime_col >= STR_TO_DATE('2015-07-19 17:00:01', '%Y-%m-%d %H:%i:%s')
GROUP BY FLOOR(UNIX_TIMESTAMP(datetimecol) / (60 * 60 / 3) )

答案 2 :(得分:0)

假设你有3个小时的间隔

CREATE TABLE T
(dcol datetime,b INT);

INSERT INTO t
VALUES('2015-07-19 17:00:01',23),
('2015-07-19 18:30:01',25),
('2015-07-19 19:00:01',66),
('2015-07-19 20:00:01',99),
('2015-07-19 21:00:01',5),
('2015-07-19 23:00:01',2),
('2015-07-20 02:00:01',78),
('2015-07-20 03:00:01',9),
('2015-07-20 05:00:01',11),
('2015-07-20 07:00:01',29)

SELECT t.dcol,t.b
FROM t JOIN t tt WHERE t.dcol=tt.dcol+INTERVAL 3 HOUR
UNION
SELECT tt.dcol,tt.b
FROM t JOIN t tt WHERE t.dcol=tt.dcol+INTERVAL 3 HOUR
ORDER BY dcol

dcol                 b
2015-07-19 17:00:01  23
2015-07-19 20:00:01  99
2015-07-19 23:00:01  2
2015-07-20 02:00:01  78
2015-07-20 05:00:01  11