我有一张名为“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/