MySQL显示按时间段分组的统计信息

标签 mysql datetime group-by

我有一张名为“reservation”的表,其中包含以下字段:

`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(150) NOT NULL,
`begin_time` datetime NOT NULL,
`end_time` datetime NOT NULL,
`node_id` int(11) NOT NULL,
PRIMARY KEY (`id`)

我希望显示给定时间段内有关预订的统计信息(例如 $from - $until,值来自 php)。用户每次预订都会预订一个节点。有很多节点可以预订,我使用以下查询来按日期显示预订统计信息。

SELECT DATE(begin_time) `Date`, count(id) as reservations
FROM reservation
WHERE begin_time > '" . $from . "'
AND end_time < '" . $until . "'
GROUP BY Date"

现在我想统计一天中哪个时间段更活跃。一天的 24 小时分为 48 个 30 分钟的时段。在我的表中,所有 begin_date 和 end_date 值都是整数,例如 2011-04-11 20:00:00 或 2011-04-11 14:30:00。预订的持续时间可以是 30 分钟、60 分钟等,最多 4 小时。

我希望我的统计数据采用以下格式(或多或少)

    Time slot       | reservations
----------------------------------
00:00:00 - 00:30:00 |     23
00:30:00 - 01:00:00 |     12
01:00:00 - 01:30:00 |     20
01:30:00 - 02:00:00 |     66
02:00:00 - 02:30:00 |     12
                and so on

你能帮我进行 SQL 查询吗?

编辑:我现在看到 PostgreSQL 有一些范围类型和运算符,例如 <@(范围包含于)documentation here 。这是否意味着如果我使用 Postgres,我的查询会更容易? MySQL 有类似的东西吗?

编辑2:谢谢你,tombom。实际上,我更改了您的答案,从 select 子句和 group by 子句中删除了 DATE(begin_time) AS Date ,因为我想查看一天中的哪些时间是最活跃的许多天的时期。我可以接受 1 小时而不是 30 分钟的粒度。 但我想问你第一句话到底是什么意思。如果预订于 01:00:00 开始并于 03:00:00 结束,我实际上希望它在两个时间段上都计算在内。

最佳答案

In my table, all the begin_date and end_date values are round numbers like 2011-04-11 20:00:00 or 2011-04-11 14:30:00

除非您也有像 2011-04-11 14:15:00 这样的时间,否则您想要的以 30 分钟为步长的结果没有多大意义,除非您想将某些预订计算两次.

除了 MySQL 中的情况之外,它会是这样的:

SELECT 
DATE(begin_time) AS `Date`,
CASE 
WHEN TIME(begin_time) >= '00:00:00' AND TIME(begin_time) < '01:00:00' THEN '00:00:00 - 01:00:00' 
WHEN TIME(begin_time) >= '01:00:00' AND TIME(begin_time) < '02:00:00' THEN '01:00:00 - 02:00:00' 
/*...and so on...*/
END AS `TimeSlot`,
COUNT(id) as reservations
FROM reservation
WHERE begin_time > '" . $from . "'
AND end_time < '" . $until . "'
GROUP BY `Date`, `TimeSlot`

我将时间段设置为 1 小时,并添加了要分组的日期。

其实,傻瓜,现在想想,当你有正好一小时的时间段时,你也可以这样做:

SELECT 
DATE(begin_time) AS `Date`,
HOUR(begin_time) AS `TimeSlot`,
COUNT(id) as reservations
FROM reservation
WHERE begin_time > '" . $from . "'
AND end_time < '" . $until . "'
GROUP BY `Date`, `TimeSlot`

更新:

SELECT 
CASE 
WHEN TIME(begin_time) BETWEEN '00:00:00' AND '01:00:00' OR TIME(end_time) BETWEEN '00:00:00' AND '01:00:00' THEN '00:00:00 - 01:00:00' 
WHEN TIME(begin_time) BETWEEN '01:00:00' AND '02:00:00' OR TIME(end_time) BETWEEN '01:00:00' AND '02:00:00' THEN '01:00:00 - 02:00:00' 
/*...and so on...*/
END AS `TimeSlot`,
COUNT(id) as reservations
FROM reservation
WHERE begin_time > '" . $from . "'
AND end_time < '" . $until . "'
GROUP BY `TimeSlot`

关于MySQL显示按时间段分组的统计信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15892805/

相关文章:

mysql - 使用 mysql 从某一行开始选择

php - Codeigniter Ajax 删除一条记录并返回可用记录数

MySQL 查询运行失败,但没有显示错误

c# - 判断某个时区的时间是否在一个范围内

mysql - GROUP BY 仅主键,但选择其他值

mysql - 多列的不同计数

java - ZonedDateTime.parse 不适用于解析 am 或 pm 时间

java - 在下周六之前获取毫秒数

sql - 查找昨天日期每个 BUYER_ID 的 TOP 10 最新记录

mysql - mysql中一张表的重复数据的平均值