时间重叠在sql代码中

时间:2014-05-14 12:08:02

标签: sql sql-server

我有一张桌子:

  ---------------------------------------------------
    ***************************************************
    worker | job | starttime        | endtime
    ---------------------------------------------------
    w1     | j1  | 2014-01-02 08:00 | 2014-01-02 10:00 
    ---------------------------------------------------
    w1     | j2  | 2014-01-02 08:00 | 2014-01-02 11:00
    ---------------------------------------------------
    w1     | j3  | 2014-01-02 09:00 | 2014-01-02 12:00
  ---------------------------------------------------
    w1     | j4  | 2014-01-02 12:00 | 2014-01-02 13:00
 ---------------------------------------------------
    w1     | j1  | 2014-01-02 12:00 | 2014-01-02 13:00

我希望结果为

w1的j1是2小时
w1的j2是1小时
w1的j3是1小时 ,就像额外的时间一样 w1的j4是1小时

例如,在准备蛋糕时,同时涂面粉和鸡蛋,但涂蛋需要更长的时间 找到总时间很容易,但我怎么能把它们分开呢? 是否可以在sql中编写代码?

2 个答案:

答案 0 :(得分:0)

查看DATEDIFF

  

返回指定datepart的count(有符号整数)   在指定的startdate和enddate之间交叉的边界。   (对于时间段也是如此)

select worker,job, DATEDIFF(HOUR,endtime,starttime) as diff from mytable

答案 1 :(得分:0)

我编辑了我的答案来处理结束时间等于上一个结束时间的情况。

所以这就是你想要的东西。我们采取最大结束时间

  • 这份工作不是现在的工作而且
  • 结束时间小于当前行的结束时间
  • 并比较当前行的结束时间,以确定当前行延长上一个作业的时间。

如果该响应为null,则该行是作业中的第一行,在这种情况下,我们只使用start和end之间的差异。

如果结束时间等于上一个结束时间,由于row_number在结束时间分区时大于1,我们输出零作为时间,因为那是该行与前一行之间的差异。

请注意"时间"数据类型限制为24小时,因此它可能不是输出的适当数据类型。我刚刚使用它,因为它为示例中的时间生成了漂亮的结果。

declare @times table (
    rowId int identity,
    worker varchar(10),
    job varchar(10),
    starttime datetime,
    endtime datetime
)

insert into @times (worker,job,starttime,endtime)
      select 'w1','j1','2014-01-02 08:00','2014-01-02 9:25'
union select 'w1','j2','2014-01-02 08:00','2014-01-02 11:00'
union select 'w1','j3','2014-01-02 09:00','2014-01-02 12:00'
union select 'w1','j4','2014-01-02 12:00','2014-01-02 14:22'
union select 'w1','j5','2014-01-02 12:00','2014-01-02 14:22'

select *, 
    case when 
        ROW_NUMBER() over (partition by endtime order by starttime,endtime) > 1 then cast('0:00' as time)
    else 
        coalesce(
            cast((endtime - (select max(endtime) from @times where endtime < t.endtime)) as time),
            cast((endtime - starttime) as time)
        )
    end as differential3
from @times t