SQL Server中的时差计算

时间:2018-02-01 04:02:57

标签: sql-server sql-server-2008

我有一个关于SQL Server的问题:如何通过empid和time计算时间差。如果时差超过5小时,则状态显示1,否则为0。

CREATE TABLE [dbo].[Timecal]
(
    [Emp ID] [float] NULL,
    [time] [datetime] NULL
) ON [PRIMARY]
GO


INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-02T09:00:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-02T10:30:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-03T09:30:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-03T12:30:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-03T12:40:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-03T17:10:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-03T06:30:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-03T08:30:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-05T23:30:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-06T01:55:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-06T02:15:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-06T06:10:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-02T11:00:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-02T12:00:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-02T13:00:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-06T14:01:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-06T15:01:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-06T15:20:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (1, CAST(N'2017-08-06T20:01:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (5, CAST(N'2017-08-02T23:30:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (5, CAST(N'2017-08-03T01:30:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (5, CAST(N'2017-08-03T01:40:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (5, CAST(N'2017-08-03T04:00:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (5, CAST(N'2017-08-03T04:30:00.000' AS DateTime))
GO
INSERT [dbo].[Timecal] ([Emp ID], [time]) VALUES (5, CAST(N'2017-08-03T06:00:00.000' AS DateTime))
GO

根据以上数据,我想要输出如下:

Emp ID  |time                           |status
--------+-------------------------------+------
  1     | 2017-08-02 09:00:00.000       | 1
  1     | 2017-08-02 10:30:00.000       | 0
  1     | 2017-08-02 11:00:00.000       | 0
  1     | 2017-08-02 12:00:00.000       | 0
  1     | 2017-08-02 13:00:00.000       | 0
  1     | 2017-08-03 06:30:00.000       | 1
  1     | 2017-08-03 08:30:00.000       | 0
  1     | 2017-08-03 09:30:00.000       | 0
  1     | 2017-08-03 12:30:00.000       | 0
  1     | 2017-08-03 12:40:00.000       | 0
  1     | 2017-08-03 17:10:00.000       | 0
  1     | 2017-08-05 23:30:00.000       | 1
  1     | 2017-08-06 01:55:00.000       | 0
  1     | 2017-08-06 02:15:00.000       | 0
  1     | 2017-08-06 06:10:00.000       | 0
  1     | 2017-08-06 14:01:00.000       | 1
  1     | 2017-08-06 15:01:00.000       | 0
  1     | 2017-08-06 15:20:00.000       | 0
  1     | 2017-08-06 20:01:00.000       | 0
  5     | 2017-08-02 23:30:00.000       | 1
  5     | 2017-08-03 01:30:00.000       | 0
  5     | 2017-08-03 01:40:00.000       | 0
  5     | 2017-08-03 04:00:00.000       | 0
  5     | 2017-08-03 04:30:00.000       | 0
  5     | 2017-08-03 06:00:00.000       | 0

我试过如下:

select  
    i.*, 
    case 
       when datediff(hh, i.Time , o.Time) <= 5 
          then 0 
          else 1 
    end status
from
    Timecal o    
join  
    Timecal i on i.[emp id] = o.[emp id] and o.time < i.time
order by 
    i.time 

但它没有返回预期的输出。

请告诉我如何在SQL Server中完成此任务。

1 个答案:

答案 0 :(得分:2)

使用Row_number订购您的表格。然后加入前一行进行比较

with cte as (
    select
        *, row_number() over (partition by [Emp ID] order by time) rn
    from
        Timecal
)

select
    a.[Emp ID], a.time, status = case when datediff(hh, b.time, a.time) < 5 then 0 else 1 end
from
    cte a
    left join cte b on a.[Emp ID] = b.[Emp ID] and a.rn - 1 = b.rn