从特定日期时间开始,按日期时间桶对MYSQL行进行分组
假设我有几列,其中一列的日期时间如下:从特定日期时间开始,按日期时间桶对MYSQL行进行分组,mysql,sql,group-by,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
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#应用程序中调用它 简单的方法是创建一个包含日期和小时范围的表 这是一个关于day的例子,你需要用小时来扩展 因此,您将拥有
hour\u块
表格
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
简单的方法是创建一个包含日期和小时范围的表 这是一个关于day的例子,你需要用小时来扩展 因此,您将拥有
hour\u块
表格
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
我将通过将值转换为最接近的前3小时周期来处理此问题。使用
到_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) )
我将通过将值转换为最接近的前3小时周期来处理此问题。使用到_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) )
假设你有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
假设你有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
按楼层分组(unix\u时间戳(datetime\u col)/(3*3600))怎么样?按楼层分组(unix\u时间戳(datetime\u col)/(3*3600)怎么样
?范围条件下的联接不能使用索引。@Vatev你能分享一些文档来描述这一事实吗?事实不需要文档:)在这种情况下,它实际上比范围条件问题更糟糕,因为联接使用两个不同的列,即使可以在一个范围上联接,也只会使用其中一个列(在这种情况下,它与没有索引一样糟糕)@ VATEV是的,他们需要一个,如果你不提供一个证明只是一个假设。把它当作一个警告。任何决定使用它的人都应该检查查询计划并考虑性能的影响。我的目标不是证明你错了或者任何这样的事情。连接范围条件不能使用索引。@ VATEV你能分享一些文档吗?描述这个事实?事实不需要文档:)在这种情况下,它实际上比范围条件问题更糟糕,因为连接使用两个不同的列,即使可以在一个范围上连接,也只会连接其中一个(在这种情况下,这与没有索引一样糟糕)。@Vatev是的,他们需要一个,如果你不提供证据,那只是一个假设。把它当作一个警告。决定使用此选项的任何人都应该检查查询计划并考虑性能影响。我的目标不是要证明你错了或诸如此类的事情,这是行不通的。我需要分组,这样我可以在3小时内对值进行一些聚合。这将不起作用。我需要分组,以便在3小时内对值进行聚合