按值集分组

发布于 2024-11-30 02:42:04 字数 403 浏览 1 评论 0原文

对于报告,我正在尝试查询不同班次的事件。轮班从每天早上 6 点、下午 2 点和晚上 10 点开始,表中的所有数据都标有日期时间时间戳。以前,墓地轮班没有做任何重要的事情,因此一个简单的 group by DATE(stamp) 就足够了,但现在是 24/7,我需要将其分解为轮班。

谁能向我解释如何使用单个 group by 子句来组合某个范围或一组值中的日期时间值?困难在于每个墓地轮班跨越两个日历日。

我考虑过用 24 小时和轮班号码填充一个表,然后将其外部连接并按日期(戳记)、小时(戳记)分组,但这看起来很黑客,甚至可能不起作用,再加上它每天会给出 24 个值,而不是 3 个,然后必须将它们合并到超级查询或脚本中。

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

for a report I'm trying to query events from different shifts. The shifts start on 6 am, 2 pm, and 10 pm every day, and all of the data in the table is tagged with a datetime timestamp. Previously the graveyard shift wasn't doing anything important, so a simple group by DATE(stamp) was sufficient, but now it's 24/7 and I need to break it down into shifts.

Can anyone explain to me how to use a single group by clause to combine datetime values from a range or a set of values? The difficulty is that each graveyard shift spans two calendar days.

I've considered populating a table with 24 hours and shift numbers, then outer joining it and group by DATE(stamp), HOUR(stamp), but that seems hackish and possibly not even working, plus it would give 24 values for each day instead of 3, which then have to be combined in a superquery or script.

MySQL-specific is perfectly ok, that's all we ever use in the reporting.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

自由范儿 2024-12-07 02:42:04

由于它们都是 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 |
+---------------------+---------------------+

Since they are all 8-hour shifts, offset by 6 hours from starting at midnight, you turn Stamp into the start-of-shift time like this:

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;

This substracts 6 hours, then rounds the hour down to either 0 1 or 2 by using integer division, then expands it out again.

Here's the test code with some edge cases:

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');

Output of above query:

+---------------------+---------------------+
| 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 |
+---------------------+---------------------+
巨坚强 2024-12-07 02:42:04

试试这个:

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

这应该让你的所有班次都在同一天

Try this:

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

That should keep all your shifts on the same day

花开雨落又逢春i 2024-12-07 02:42:04

我认为你应该采用“带有时间和轮班号码的表格”方法。此外,我认为您应该考虑使用 日历表 即不仅涵盖 24 小时的表格,还涵盖您企业的预期需求的整个过去、现在和未来。这并不是黑客行为:相反,这是一种经过尝试和测试的方法。这个想法是,SQL 是一种声明性语言,旨在查询表中的数据,因此声明性的数据驱动解决方案非常有意义。

I think you should pursue your "table with hours and shift numbers" approach. Further, I think you should consider using a calendar table i.e. a table not just covering 24 hours but the whole past, present and future of your enterprise's expected needs. This is not hackish: rather, it is a tried and tested approach. The idea is that SQL is a declarative language designed to query data in tables so a declarative, data-driven solutions make a lot of sense.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文