我对SQL Server有疑问:如何计算当前和上一行之间的分钟差异?
示例数据:表格step1
:
CREATE TABLE [dbo].[step1]
(
[Emp ID] [float] NULL,
[time] [datetime] NULL,
[gr] [int] NOT NULL,
[group_] [int] NULL
) ON [PRIMARY]
GO
INSERT [dbo].[step1] ([Emp ID], [time], [gr], [group_])
VALUES (1, CAST(N'2017-08-02T09:00:00.000' AS DateTime), 1, 1),
(1, CAST(N'2017-08-02T10:30:00.000' AS DateTime), 0, 1),
(1, CAST(N'2017-08-02T11:00:00.000' AS DateTime), 0, 1),
(1, CAST(N'2017-08-02T12:00:00.000' AS DateTime), 0, 1),
(1, CAST(N'2017-08-02T13:00:00.000' AS DateTime), 0, 1),
(1, CAST(N'2017-08-03T06:30:00.000' AS DateTime), 1, 2),
(1, CAST(N'2017-08-03T08:30:00.000' AS DateTime), 0, 2),
(1, CAST(N'2017-08-03T09:30:00.000' AS DateTime), 0, 2),
(1, CAST(N'2017-08-03T12:30:00.000' AS DateTime), 0, 2),
(1, CAST(N'2017-08-03T12:40:00.000' AS DateTime), 0, 2),
(1, CAST(N'2017-08-03T17:10:00.000' AS DateTime), 0, 2),
(1, CAST(N'2017-08-05T23:30:00.000' AS DateTime), 1, 3),
(1, CAST(N'2017-08-06T01:55:00.000' AS DateTime), 0, 3),
(1, CAST(N'2017-08-06T02:15:00.000' AS DateTime), 0, 3),
(1, CAST(N'2017-08-06T06:10:00.000' AS DateTime), 0, 3),
(1, CAST(N'2017-08-06T14:01:00.000' AS DateTime), 1, 4),
(1, CAST(N'2017-08-06T15:01:00.000' AS DateTime), 0, 4),
(1, CAST(N'2017-08-06T15:20:00.000' AS DateTime), 0, 4),
(1, CAST(N'2017-08-06T20:01:00.000' AS DateTime), 0, 4),
(5, CAST(N'2017-08-02T23:30:00.000' AS DateTime), 1, 1),
(5, CAST(N'2017-08-03T01:30:00.000' AS DateTime), 0, 1),
(5, CAST(N'2017-08-03T01:40:00.000' AS DateTime), 0, 1),
(5, CAST(N'2017-08-03T04:00:00.000' AS DateTime), 0, 1),
(5, CAST(N'2017-08-03T04:30:00.000' AS DateTime), 0, 1),
(5, CAST(N'2017-08-03T06:00:00.000' AS DateTime), 0, 1);
根据以上数据,我想要输出如下:
Emp ID | Time | gr | group_ | diffminutes
-------+-------------------------+----+--------+-------------
1 | 2017-08-02 09:00:00.000 | 1 | 1 | 90
1 | 2017-08-02 10:30:00.000 | 0 | 1 | 30
1 | 2017-08-02 11:00:00.000 | 0 | 1 | 60
1 | 2017-08-02 12:00:00.000 | 0 | 1 | 60
1 | 2017-08-02 13:00:00.000 | 0 | 1 | NULL
1 | 2017-08-03 06:30:00.000 | 1 | 2 | 120
1 | 2017-08-03 08:30:00.000 | 0 | 2 | 60
1 | 2017-08-03 09:30:00.000 | 0 | 2 | 180
1 | 2017-08-03 12:30:00.000 | 0 | 2 | 10
1 | 2017-08-03 12:40:00.000 | 0 | 2 | 270
1 | 2017-08-03 17:10:00.000 | 0 | 2 | NULL
1 | 2017-08-05 23:30:00.000 | 1 | 3 | 145
1 | 2017-08-06 01:55:00.000 | 0 | 3 | 20
1 | 2017-08-06 02:15:00.000 | 0 | 3 | 235
1 | 2017-08-06 06:10:00.000 | 0 | 3 | NULL
1 | 2017-08-06 14:01:00.000 | 1 | 4 | 60
1 | 2017-08-06 15:01:00.000 | 0 | 4 | 19
1 | 2017-08-06 15:20:00.000 | 0 | 4 | 281
1 | 2017-08-06 20:01:00.000 | 0 | 4 | NULL
5 | 2017-08-02 23:30:00.000 | 1 | 1 | 120
5 | 2017-08-03 01:30:00.000 | 0 | 1 | 10
5 | 2017-08-03 01:40:00.000 | 0 | 1 | 140
5 | 2017-08-03 04:00:00.000 | 0 | 1 | 30
5 | 2017-08-03 04:30:00.000 | 0 | 1 | 90
5 | 2017-08-03 06:00:00.000 | 0 | 1 | NULL
我尝试过以下查询:
select
a.[Emp ID], a.Time,
datediff(mi, a.Time, b.Time) diffminutes
from
(select
*,
row_number() over (partition by [Emp ID], group_ order by time) as rn
from
step1) a
left join
(select
*,
row_number() over (partition by [Emp ID], group_ order by time) as rn
from
step1) b on a.[Emp ID] = b.[Emp ID]
and a.rn = b.rn + 1
order by
a.Time
但它没有返回预期的结果。
请告诉我如何在SQL Server中完成此任务?
答案 0 :(得分:3)
尝试使用SQL Server 2008:
;with cte as
(select *,ROW_NUMBER() OVER (PARTITION BY GROUP_ ORDER BY [time]) as rownumber
from step1
)
select c1.* ,abs(datediff(minute,c2.[time],c1.[time]))
from cte c1
left join
cte c2
on c1.[emp id]=c2.[emp id]
and c1.group_=c2.group_
and c1.rownumber+1=c2.rownumber
order by c1.[emp id],c1.[time]
从SQL Server 2012版开始,这变得更加简单:
select
*,
abs(datediff(minute,
lead([time]) over (partition by [emp id], group_ order by [time]), time)) as diff
from step1