超过午夜的SQL分裂时间

时间:2016-11-24 20:52:16

标签: sql

我正在寻求从我们的MIS数据库中获取有用信息的最佳方法的一些指导

场景: - 我想通过我可以深入研究的可变周期检查员工利用率。这需要分成几天,以便我可以在24小时内评估所做的事情

表格很大,我们需要计算大量的列,所以理想情况下我需要将跨越2天的记录拆分为2

该表有一个datetimeformat字段,其中包含用户[starttime],然后它有一个单独的字段,其[duration]为十进制小时。

所以一个例子是:

ID   StartTime              Duration      Qty      username
1    2016-11-24 23:00:00       2.00       1000      Joe Bloggs

在上面的示例中,Joe从晚上11点开始工作到凌晨1点,所以我需要的是以某种方式在我的查询中将此记录拆分为在午夜之前将任何内容作为1条记录和之后的任何内容放入另一条记录中此示例非常简单,因为它是一半/一半,但有些可能会在晚上10点开始,并在下午6点结束,所以我需要2小时6小时。

不确定最好的方法是这样做,我最初的想法是创建一个cte,其中开始时间是1天,如果开始时间+持续时间是在第二天,则分割记录。

不确定是否有更简单的方法,或者是否有人必须这样做。

任何帮助表示赞赏

2 个答案:

答案 0 :(得分:0)

@Joe有正确的想法,这里是伪SQL

SELECT ID,StartTime,Duration,Qty,username
WHERE TRUNCATE(StartTime,DAY) = TRUNCATE(StartTime + Duration hours ,DAY)
 UNION
SELECT ID,StartTime, TRUNCATE(StartTime,DAY) + 1 days - StartTime hours ,Qty,username
WHERE TRUNCATE(StartTime,DAY) < TRUNCATE(StartTime+Duration hours,DAY)
 UNION
SELECT ID,TRUNCATE(StartTime+Duration hour,DAY),StartTime + duration hours - DATE(StartTime+Duration),Qty,username
WHERE TRUNCATE(StartTime,DAY) < TRUNCATE(StartTime+Duration hours,DAY)

TRUNCATE(timestamp,DAY)将时间戳截断为YYYY-MM-DD 00:00:00

答案 1 :(得分:0)

您可以将行与join相乘。制作Tally表,简单的表格,数字1,2,3 ......并进行连接。我将在这里使用从零开始的表:

CREATE TABLE Tally0 (Number INT IDENTITY(0,1) PRIMARY KEY NOT NULL);
GO

INSERT INTO Tally0 DEFAULT VALUES;
GO 10000

现在更难的部分是日期和数字之间的转换:

;WITH 
tmp1 AS (SELECT *, 
           DATEDIFF(SECOND, CONVERT(DATE, StartTime), StartTime)/3600.0
           + DATEPART(NANOSECOND, StartTime)/(3600*1000000000.0) AS startingHours
         FROM Record),

tmp2 AS (SELECT *, 
           startingHours + Duration AS endingHours,  
          (startingHours + Duration)/24.0 AS endingDays  
         FROM tmp1)

SELECT *, 
    CASE WHEN Number = 0 THEN StartTime 
         ELSE DATEADD(DAY, Number, CONVERT(DATE, StartTime)) 
    END AS StartTime2,

    CASE WHEN Number = 0 AND 1 < endingDays THEN 24 - startingHours
         WHEN Number = 0 THEN Duration
         WHEN Number + 1 < endingDays THEN 24
         ELSE endingHours - Number * 24 
    END AS Duration2

FROM tmp2 
JOIN Tally0 ON Number < endingDays