报告我试图查询不同班次的事件。班次从每天早上6点,下午2点和晚上10点开始,表格中的所有数据都标有日期时间戳。之前的墓地转移没有做任何重要的事情,所以一个简单的group by DATE(stamp)
已经足够了,但是现在它是24/7,我需要把它分解成轮班。
有人可以向我解释如何使用单个group by
子句组合一个范围或一组值的日期时间值吗?困难在于每个墓地班次跨越两个日历日。
我考虑过24小时填充一个表并移动数字,然后外部连接它和group by DATE(stamp), HOUR(stamp)
,但这似乎是hackish,甚至可能都没有工作,而且它会给每天24个值而不是3个,然后必须在超级查询或脚本中组合。
MySQL特定是完全正常的,这就是我们在报告中使用的所有内容。
答案 0 :(得分: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;
这减少了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 |
+---------------------+---------------------+
答案 1 :(得分:0)
试试这个:
GROUP BY DATE(DATE_ADD(Stamp,INTERVAL -6 HOUR))
那应该在同一天保留所有轮班
答案 2 :(得分:0)
我认为你应该追求你的“带小时和班次数字的桌子”的方法。此外,我认为您应该考虑使用calendar table表,而不仅仅是24小时的表,而是整个过去,现在和未来企业的预期需求。这不是hackish:相反,它是一种久经考验的方法。这个想法是SQL是一种声明性语言,用于查询表中的数据,因此声明性的,数据驱动的解决方案很有意义。