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

时间:2013-04-09 03:32:01

标签: 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有一些范围类型和运算符,例如&lt; @(范围包含)documentation here。如果我使用Postgres,这是否意味着我的查询会更容易? MySQL有类似的东西吗?

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

1 个答案:

答案 0 :(得分:1)

  

在我的表中,所有begin_date和end_date值都是圆形数字,如2011-04-11 20:00:00或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`