2011-08-17 58 views
1

我正在尝试查询来自不同班次的事件。班次开始时间为每天上午6点,下午2点和晚上10点,表格中的所有数据均标记有日期时间时间戳。之前墓地转变并没有做任何重要的事情,所以简单的group by DATE(stamp)就足够了,但现在是24/7,我需要把它分解成几个班次。分组通过值集

任何人都可以向我解释如何使用单个group by子句来结合一个范围或一组值的日期时间值?困难在于每个墓地的移动都跨越两个日历日。

我已经考虑用24小时填充表格并移动数字,然后外加入它并且group by DATE(stamp), HOUR(stamp),但这看起来很破烂,甚至可能不工作,再加上它会给每天24个值而不是3个,然后必须结合在一个superquery或脚本中。

特定于MySQL的完全可以,这就是我们在报告中使用的所有功能。

回答

2

因为都是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; 

这substracts 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 | 
+---------------------+---------------------+ 
+0

这看起来像一个很好的解决方案,似乎对我的测试数据非常有效,并且从该输出获取日期和转换#会非常简单。我现在将把它整合到我的报告中。非常感谢! – SilverbackNet

0

试试这个:

GROUP BY DATE(DATE_ADD(Stamp,INTERVAL -6 HOUR)) 

这应该保持在同一天所有的班次

0

我想你应该“以小时表和移位号”追求你的方法。此外,我认为你应该考虑使用calendar table,即表格不仅涵盖了24小时,还包括企业预期需求的整个过去,现在和未来。这不是冒险的,而是一种久经考验的方法。这个想法是,SQL是一种声明式语言,用于查询表中的数据,所以声明式的,数据驱动的解决方案很有意义。