我的表有示例数据,我需要计算两列中两个时间戳之间的业务时间。营业时间:上午9:00至下午5:00,周六和周日疏忽,我不考虑公共假期。有人可以提供一些如何实现这一目标的指导方针吗?我想要第3栏中所述的所需输出,日期格式为:yyyy-mm-dd
Created date Updated date Business hrs
2012-03-05 9:00am 2012-03-05 3:00pm 6
2012-03-05 10:00am 2012-03-06 10:00am 9
2012-03-09 4:00pm 2012-03-19 10:00am 2
答案 0 :(得分:17)
问题是不应该考虑公众假期,所以这个答案就是这样 - 计算考虑周末的营业时间,但忽略可能的公众假期。
如果您需要考虑公共假期,您需要有一个单独的表格,列出公共假期的日期,这些日期可能因年度和州与州或国家而异。主要公式可能保持不变,但您需要从公共假期的结果小时数中减去给定的日期范围。
让我们创建一个包含一些涵盖各种情况的样本数据的表:
CREATE TABLE T (CreatedDate datetime, UpdatedDate datetime);
INSERT INTO T VALUES
('2012-03-05 09:00:00', '2012-03-05 15:00:00'), -- simple part of the same day
('2012-03-05 10:00:00', '2012-03-06 10:00:00'), -- full day across the midnight
('2012-03-05 11:00:00', '2012-03-06 10:00:00'), -- less than a day across the midnight
('2012-03-05 10:00:00', '2012-03-06 15:00:00'), -- more than a day across the midnight
('2012-03-09 16:00:00', '2012-03-12 10:00:00'), -- over the weekend, less than 7 days
('2012-03-06 16:00:00', '2012-03-15 10:00:00'), -- over the weekend, more than 7 days
('2012-03-09 16:00:00', '2012-03-19 10:00:00'); -- over two weekends
在MS SQL Server中,我使用以下公式:
SELECT
CreatedDate,
UpdatedDate,
DATEDIFF(minute, CreatedDate, UpdatedDate)/60.0 -
DATEDIFF(day, CreatedDate, UpdatedDate)*16 -
DATEDIFF(week, CreatedDate, UpdatedDate)*16 AS BusinessHours
FROM T
产生以下结果:
+-------------------------+-------------------------+---------------+
| CreatedDate | UpdatedDate | BusinessHours |
+-------------------------+-------------------------+---------------+
| 2012-03-05 09:00:00 | 2012-03-05 15:00:00 | 6 |
| 2012-03-05 10:00:00 | 2012-03-06 10:00:00 | 8 |
| 2012-03-05 11:00:00 | 2012-03-06 10:00:00 | 7 |
| 2012-03-05 10:00:00 | 2012-03-06 15:00:00 | 13 |
| 2012-03-09 16:00:00 | 2012-03-12 10:00:00 | 2 |
| 2012-03-06 16:00:00 | 2012-03-15 10:00:00 | 50 |
| 2012-03-09 16:00:00 | 2012-03-19 10:00:00 | 42 |
+-------------------------+-------------------------+---------------+
它有效,因为在SQL Server DATEDIFF
中返回指定的 startdate 和 enddate datepart 边界的计数>
每天有8个工作小时。我计算两个日期之间的总小时数,然后减去中午的数量乘以每天16个非营业时间,然后减去周末的数量乘以16(周六+周日的8 + 8个工作小时)。
它还假设给定的开始和结束日期/时间是在营业时间内。
在MySQL中,最接近的等价物是TIMESTAMPDIFF
,但它的工作方式不同。它有效地计算以秒为单位的差异,并将所选单位中的秒数除以(丢弃小数部分)。
因此,要获得我们需要的结果,我们可以计算某个锚定日期时间与TIMESTAMPDIFF
和CreatedDate
之间的UpdatedDate
,而不是计算CreatedDate
和{{之间的差异1}}直接。
我选择了UpdatedDate
,这是星期一。您可以选择任何其他星期一(或星期日,如果您的星期日从星期日开始)午夜为锚定日期。
MySQL查询变为(参见SQL Fiddle):
2000-01-03 00:00:00
答案 1 :(得分:3)
创建一个名为BusinessHours的表,其中一个名为Hour的列包含日期时间。 Make Hour是主键。编写一个流程来填充一年中的每个工作小时(2012-01-02 00:90:00, 2012-01-02 00:10:00
等)。这应该不难,因为规则很简单。这听起来像是很多数据,但在宏观方案中却并非如此(一年只有8760小时 - 即使你的日期时间分别为8个字节,这也是一个惊人的60kB)。确保安排作业以保持其填充。
然后:
Select
y.CreatedDate,
y.UpdatedDate,
Count(*) as BusinessHours
From
YourTable y
Inner Join
BusinessHours h
On h.Hour >= y.CreatedDate And h.Hour < y.UpdatedDate
Group By
y.CreatedDate,
y.UpdatedDate
如果您考虑过公共假期,这也为您提供了一种相当简单的方法 - 只需从BusinessHours表中取出行。
答案 2 :(得分:0)
试
SELECT (FLOOR(DATEDIFF (UpdatedDate, CreatedDate) / 7) * 5 + MOD (DATEDIFF (UpdatedDate, CreatedDate), 7)) * 8 +
TIMEDIFF (TIME (UpdatedDate), TIME(CreatedDate))
FROM YourTable
以上内容并不完整,因为它只是“估算”周末......但它应该让你开始......另一种选择是使用有效营业时间表(详见this answer from Laurence)。
有关参考,请参阅MySQL documentation。
答案 3 :(得分:0)
使用datediff计算开始和结束时间之间的差异,然后减去(date_add,负时数)非工作时间:24周末天,16天工作日预计结束和开始日需要额外的计算。 是否一天是周末,可以使用dayofweek方法指定。