对于一个报告,我试图从不同的班次查询事件。每天早上6点、下午2点和晚上10点开始轮班,表中的所有数据都用日期时间戳标记。以前墓地轮班没有什么重要的事情,所以一个简单的group by DATE(stamp)就足够了,但现在已经是24/7了,我需要把它分解成几个轮班。
有人能给我解释一下如何使用一个group by子句组合一个范围或一组值中的datetime值吗?困难在于每个墓地轮班的时间跨度为两个日历日。
我已经考虑过用24小时和班次号填充一个表,然后外部加入它并group by DATE(stamp), HOUR(stamp),但这看起来有些老套,甚至可能不起作用,而且它将为每天提供24个值,而不是3个值,然后这些值必须组合在一个超级查询或脚本中。
MySQL特有的功能非常好,这就是我们在报告中所使用的全部功能。

最佳答案

因为它们都是8小时轮班制,从午夜开始偏移6小时,所以您将Stamp转换为轮班开始时间,如下所示:

select
    stamp,
    adddate(date(subdate(stamp, interval 6 hour)),
      interval ((hour(subdate(stamp, interval 6 hour))
      div 8) * 8) + 6 hour) as shift_start
from mytable;

这将减去6小时,然后使用整数除法将小时向下舍入到0 1或2,然后再次将其展开。
下面是一些边缘案例的测试代码:
create table mytable (stamp datetime);
insert into mytable values ('2011-08-17 22:00:00'), ('2011-08-17 23:01:00'),
('2011-08-18 00:02:00'), ('2011-08-18 05:59:00'), ('2011-08-18 06:00:00'),
('2011-08-18 13:59:00'), ('2011-08-18 14:00:00'), ('2011-08-18 17:59:00');

上述查询的输出:
+---------------------+---------------------+
| stamp               | shift_start         |
+---------------------+---------------------+
| 2011-08-17 22:00:00 | 2011-08-17 22:00:00 |
| 2011-08-17 23:01:00 | 2011-08-17 22:00:00 |
| 2011-08-18 00:02:00 | 2011-08-17 22:00:00 |
| 2011-08-18 05:59:00 | 2011-08-17 22:00:00 |
| 2011-08-18 06:00:00 | 2011-08-18 06:00:00 |
| 2011-08-18 13:59:00 | 2011-08-18 06:00:00 |
| 2011-08-18 14:00:00 | 2011-08-18 14:00:00 |
| 2011-08-18 17:59:00 | 2011-08-18 14:00:00 |
+---------------------+---------------------+

关于mysql - 按值集分组,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7087178/

10-12 22:04