Employee table has four columns. Employee, Start, End, Diff. Diff column is the duration and calculated as End - Start.
I want to find the conflict between the Start and End time range. For instance, Employee A has three rows: First rows Start time is 01:02 and end time is 01:05 but second row start time is 01:03 which is a conflict in the first row data.
employee StartDate EndDate Start End Diff
A 04/08/2019 04/08/2019 01:02:00 01:05:00 3
A 04/08/2019 04/08/2019 01:03:00 01:08:00 5
A 04/08/2019 04/08/2019 01:014:00 01:21:00 7
B 04/08/2019 04/08/2019 02:00:00 02:17:00 17
I want to only select the specific start and end time for employee A that has an overlap in their start and end time and want to calculate total length of conflict in a new column using t-sql. i'm a newbie and need help. please anyone?
SELECT TOP (100) a.ccx_employeename AS employee
,CONVERT(Date,[a].[ccx_starttime]) AS [Start Date],CONVERT(Date,[a].[ccx_endtime]) AS [End Date], CONVERT(time (0), a.ccx_starttime) AS StartTime
, CONVERT(time (0), a.ccx_endtime) AS EndTime
, CONVERT (time(0), (a.ccx_endtime - a.ccx_starttime)) AS Duration
FROM ccp_sim_MSCRM.dbo.Filteredccx_Recorded_Service as a
where CONVERT(time (0), a.ccx_starttime) BETWEEN CONVERT(time (0), a.ccx_starttime) And CONVERT(time (0), a.ccx_endtime)
As first and second rows has conflict I want to show that two rows. As well as conflict duration is 2 minutes in this example. First row end time is 01:05 but second rows start time is 01:03 so conflict duration is 01:05 - 01:03 = 2 minutes
Desired Output
employee StartDate EndDate Start End Diff
A 04/08/2019 04/08/2019 01:02:00 01:05:00 3
A 04/08/2019 04/08/2019 01:03:00 01:08:00 5
duration of conflict : 2 mins
答案 0 :(得分:0)
I would join the table over itself, though maybe not the most effective :
SELECT
e1.employee,
e1.Start as firstStart,
e1.End as firstEnd,
e2.Start as secondStart,
e2.End as secondEnd,
e1.End - e2.Start as conflictDuration
FROM
Employee as e1 inner join
Employee as e2 on (
e1.employee = e2.employee and
e2.Start < e1.End and
e2.End > e1.Start
)
答案 1 :(得分:0)
您的问题有几个部分:
下面的解决方案仅涵盖前两部分,并假定日期和时间字段为组合字段。
我添加了一些唯一的键来对结果进行重复数据删除,并对行进行“排序”以进行比较。在下面的代码中,它是“ id”。
declare @t table (id int identity,employee char(1), StartDateTime smalldatetime, EndDateTime smalldatetime, diff as DATEDIFF(minute,StartDateTime,EndDateTime))
insert into @t values('A','2019-04-08 01:02','2019-04-08 01:05')
insert into @t values('A','2019-04-08 01:03','2019-04-08 01:08')
insert into @t values('A','2019-04-08 01:14','2019-04-08 01:21')
insert into @t values('B','2019-04-08 02:00','2019-04-08 02:17')
SELECT T1.employee, T1.StartDateTime, T1.EndDateTime, T2.StartDateTime, T2.EndDateTime
, (T1.diff + T2.diff)
- DATEDIFF(minute, CASE WHEN T1.StartDateTime < T2.StartDateTime THEN T1.StartDateTime ELSE T2.StartDateTime END -- MIN(Start)
, CASE WHEN T1.EndDateTime > T2.EndDateTime THEN T1.EndDateTime ELSE T2.EndDateTime END) -- MAX(End)
AS "duration of conflict"
FROM @t AS T1
JOIN @t AS T2
ON T2.employee = T1.employee
AND T2.id > T1.id -- Each only once
AND T2.StartDateTime < T1.EndDateTime
AND T2.EndDateTime > T1.StartDateTime
答案 2 :(得分:0)
这对我来说是使用LEAD
/ LAG
函数的理想场所。结合使用一些子查询和IIF
语句,您可以计算出所需的结果。
示例:
DECLARE @Employee TABLE
(
Employee VARCHAR(1),
startDate DATE,
endDate DATE,
[start] TIME,
[end] TIME,
diff AS DATEDIFF(MINUTE,[start],[end])
)
INSERT INTO @Employee (Employee, startDate, endDate, start, [end])
VALUES
('A',CAST('2019-04-08' AS DATE),CAST('2019-04-08' AS DATE),'01:02:00','01:05:00'),
('A',CAST('2019-04-08' AS DATE),CAST('2019-04-08' AS DATE),'01:03:00','01:08:00'),
('A',CAST('2019-04-08' AS DATE),CAST('2019-04-08' AS DATE),'01:14:00','01:21:00'),
('B',CAST('2019-04-08' AS DATE),CAST('2019-04-08' AS DATE),'02:00:00','02:17:00')
SELECT
Employee.Employee,
Employee.startDate,
Employee.endDate,
Employee.start,
Employee.[end],
diff,
(IIF(ISNULL(lagConflict,0)>0,ISNULL(lagConflict,0),0)+IIF(ISNULL(Employee.leadConflict,0)>0,ISNULL(Employee.leadConflict,0),0)) AS conflict
FROM
(
SELECT
Employee,
startDate,
endDate,
start,
[end],
diff,
DATEDIFF
(
MINUTE,
[start],
LAG([end],1)
OVER
(
PARTITION BY
Employee,
startDate,
endDate
ORDER BY
[start],
[end]
)
) AS lagConflict,
DATEDIFF
(
MINUTE,
[end],
LEAD([start],1)
OVER
(
PARTITION BY
Employee,
startDate,
endDate
ORDER BY
[start],
[end]
)
)*-1 AS leadConflict
FROM
@Employee
) AS Employee
WHERE
Employee.leadConflict > 0
OR Employee.lagConflict > 0;
Microsoft SQL文档:LAG] 1