【问题标题】:SQL Server - Calculate time between dates with work shiftsSQL Server - 计算轮班日期之间的时间
【发布时间】:2017-01-18 22:45:01
【问题描述】:

问题:仅使用班次日期计算两个日期之间的时间量。班次日期是唯一允许的时间来计算时间。因此,在下面的数据示例中,我希望独立查看每个#Rejections 记录的时差。理想情况下,我还想考虑午休时间,但如果这让这更难处理,我不考虑。

数据:

CREATE TABLE #Shifts
(
  ShiftId INT
  ,StartTime DECIMAL(6,2)
  ,EndTime DECIMAL(6,2)
  ,LunchStart DECIMAL(6,2)
  ,LunchEnd DECIMAL(6,2)
);

INSERT INTO #Shifts VALUES (1, 6.00, 16.75, 11.75, 12.50) /*6am to 4:45pm*/
INSERT INTO #Shifts VALUES (2, 17.00, 3.75, 23.00, 23.75) /*5pm to 3:45am (next day)*/
INSERT INTO #Shifts VALUES (3, 5.00, 17.75, 12.00, 12.75) /*5am to 5:45pm*/

CREATE TABLE #Rejections
(
  JobId INT
  ,WeldId INT
  ,IndicationNum INT
  ,FirstRejectedDate DATETIME
  ,LastAcceptedDate DATETIME
);

INSERT INTO #Rejections VALUES (500, 700, 2, '2017-01-03 22:35:31.000', '2017-01-04 01:38:16.000')
INSERT INTO #Rejections VALUES (500, 701, 3, '2017-01-04 01:48:55.000', '2017-01-06 09:21:11.000')

我正在寻求有关如何解决此问题的帮助。我是 SQL Server 的新手,这个问题让我很困惑。我什至不知道从哪里开始。如果对可用命令有帮助,我正在使用 SQL Server 2008 R2。有人可以帮我弄清楚如何实现这一目标吗?

【问题讨论】:

  • 您能解释一下并提供您想要的输出示例吗?
  • 您实际上是否将开始/结束时间存储为小数?如果您将它们存储为datetime,您至少可以对这些值执行datediff。之后,您可以通过datediff 查看午餐时间,然后从总花费的时间中减去。您按照上面显示的方式进行操作会使这件事变得更加困难,尤其是当您的轮班超过一天时。
  • 我使用的 ERP 系统存储了一个小数点。我不同意他们的决定。我想我必须先将其转换为日期时间。

标签: sql-server date sql-server-2008-r2


【解决方案1】:

如果可能的话,最好使用 datetime2 (not datetime 在 cmets 中的建议)——尽管我知道在你的情况下它不是。如果你这样做了,那么答案很简单且易于阅读......

SELECT DATEDIFF(mi, StartTime, EndTime) - DATEDIFF(mi, LunchStart, LunchEnd) 
FROM #shifts

我知道它不适用于你,但我想向其他人展示它,与下面的可怕代码相比。这很丑陋,但可以以十进制格式进行这些计算。此代码将为您提供午休时间(分钟)、轮班总分钟数,然后将总时间分解为小时和分钟,因此您可以随意使用。

SELECT  (CASE WHEN LunchEnd < LunchStart THEN 24 ELSE 0 END +
        LunchEnd - LunchStart) * 60 AS LunchMins
    , (CASE WHEN EndTime < StartTime THEN 24 ELSE 0 END +
        EndTime 
        - StartTime 
        - (CASE WHEN LunchEnd < LunchStart THEN 24 ELSE 0 END + LunchEnd - LunchStart))
        * 60 AS TotalShiftMins
    , ROUND((CASE WHEN EndTime < StartTime THEN 24 ELSE 0 END +
        EndTime 
        - StartTime 
        - (CASE WHEN LunchEnd < LunchStart THEN 24 ELSE 0 END + LunchEnd - LunchStart))
        ,0) AS TotalShiftHoursOnly
    , ((CASE WHEN EndTime < StartTime THEN 24 ELSE 0 END +
        EndTime 
        - StartTime 
        - (CASE WHEN LunchEnd < LunchStart THEN 24 ELSE 0 END + LunchEnd - LunchStart))
        * 60) % 60 AS TotalShiftMinsOnly
    , *
FROM #Shifts

PS 我假设您的意思是#Shifts 表而不是#Rejections 表? #Rejections 表中的数据似乎与您的要求不匹配。

【讨论】:

  • 就像我在上面在 cmets 中所说的那样,由于我使用的是 ERP 系统,我被困在使用小数表示轮班时间。我不喜欢它的设置方式。
  • 好的,这个答案有用吗?如果您愿意,我可以做一个跨日期返回小时和分钟并包括午餐时间的方法?我提出的输出格式是否适合您,还是您想要其他方式?
  • 我认为小时和分钟是我需要的。你上面的只是告诉我每个班次有多长,它没有处理跨越午夜的班次(#2)
  • 我已根据您的 cmets 更改了答案。希望对您有所帮助。
  • 我明白了。它用于获取轮班时间。谢谢你。我想我可能问这个问题很糟糕。我正在尝试计算 #Rejections 表中 FirstRejectedDate 和 LastAcceptedDate 之间的总时间。我希望它们彼此独立计算。换句话说,将每一行视为自己的。如果可以的话,我只会对它们做一个简单的 DATEDIFF 并且做得很好,但我需要知道上面给出的轮班工作的时间量。基本上,与上面给出的班次时间重叠的日期之间的时间。
猜你喜欢
  • 2010-09-17
  • 1970-01-01
  • 2021-01-16
  • 2021-01-06
  • 1970-01-01
  • 2012-03-15
  • 1970-01-01
  • 1970-01-01
  • 2012-12-01
相关资源
最近更新 更多