分组按值组

时间:2011-08-17 01:54:48

标签: mysql sql group-by

报告我试图查询不同班次的事件。班次从每天早上6点,下午2点和晚上10点开始,表格中的所有数据都标有日期时间戳。之前的墓地转移没有做任何重要的事情,所以一个简单的group by DATE(stamp)已经足够了,但是现在它是24/7,我需要把它分解成轮班。

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

我考虑过24小时填充一个表并移动数字,然后外部连接它和group by DATE(stamp), HOUR(stamp),但这似乎是hackish,甚至可能都没有工作,而且它会给每天24个值而不是3个,然后必须在超级查询或脚本中组合。

MySQL特定是完全正常的,这就是我们在报告中使用的所有内容。

3 个答案:

答案 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是一种声明性语言,用于查询表中的数据,因此声明性的,数据驱动的解决方案很有意义。