我遵循时间间隔逻辑。如果在结束时间和开始时间之间有任何时间间隔,我们必须隔离该数据。
我曾经这样查询,
DECLARE @EMP_DETAILS TABLE
(ID INT,
EMP_ID INT,
START_TIME VARCHAR(10),
END_TIME VARCHAR(10)
)
INSERT INTO @EMP_DETAILS
SELECT 1, 50, '09:30', '10:30'
UNION
SELECT 2, 50, '10:30', '11:45'
UNION
SELECT 3, 50, '11:45', '12:15'
UNION
SELECT 4, 50, '12:15', '13:40'
UNION
SELECT 5, 50, '14:00', '14:40'
UNION
SELECT 6, 50, '14:40', '15:10'
UNION
SELECT 7, 50, '15:10', '18:00'
SELECT
A.EMP_ID, A.START_TIME, A.END_TIME,
B.START_TIME, B.END_TIME
FROM
@EMP_DETAILS A
LEFT JOIN
@EMP_DETAILS B ON A.END_TIME = B.START_TIME
AND A.EMP_ID = B.EMP_ID
我的预期输出应如下所示:
EMP_ID START_TIME END_TIME RN
---------------------------------
50 09:30 10:30 1
50 10:30 11:45 1
50 11:45 12:15 1
50 14:00 14:40 2
50 14:40 15:10 2
我有希望,你清楚我要说的是什么......
提前致谢。
答案 0 :(得分:0)
我确信有一种方法可以在单个查询中计算RN
列,但我现在无法想到它。因此,通过使用游标,以下内容可以创建您想要的内容:
DECLARE @EMP_DETAILS TABLE (
ID INT,
EMP_ID INT,
START_TIME VARCHAR(10),
END_TIME VARCHAR(10)
)
DECLARE @OUTPUT TABLE (
ID INT,
EMP_ID INT,
START_TIME VARCHAR(10),
END_TIME VARCHAR(10),
RN INT NULL
)
INSERT INTO @EMP_DETAILS VALUES
(1, 50, '09:30', '10:30'),
(2, 50, '10:30', '11:45'),
(3, 50, '11:45', '12:15'),
(4, 50, '12:15', '13:40'),
(5, 50, '14:00', '14:40'),
(6, 50, '14:40', '15:10'),
(7, 50, '15:10', '18:00')
INSERT INTO @OUTPUT
SELECT A.ID, A.EMP_ID, A.START_TIME, A.END_TIME, NULL
FROM @EMP_DETAILS A
INNER JOIN @EMP_DETAILS B ON A.EMP_ID = B.EMP_ID AND A.END_TIME = B.START_TIME
DECLARE @ID INT, @I INT, @J INT = 1
SELECT @I = MIN(ID) - 1
FROM @OUTPUT
DECLARE CR CURSOR LOCAL FOR
SELECT ID
FROM @OUTPUT
ORDER BY ID
OPEN CR
FETCH NEXT FROM CR INTO @ID
WHILE @@FETCH_STATUS = 0
BEGIN
IF @ID > @I + 1
SET @J = @J + 1
UPDATE @OUTPUT
SET RN = @J
WHERE ID = @ID
SET @I = @ID
FETCH NEXT FROM CR INTO @ID
END
CLOSE CR
DEALLOCATE CR
SELECT EMP_ID, START_TIME, END_TIME, RN
FROM @OUTPUT
ORDER BY ID
我没有使用LEFT JOIN
,而是使用INNER JOIN
来消除不需要的行。然后,通过使用RN
移动@OUTPUT
表中的记录来计算CURSOR
列,以查找ID
序列中的中断。如果有休息,那么我们增加RN
。这假定ID
在实际数据中永远不会丢失数字。
这是上述查询的输出:
EMP_ID START_TIME END_TIME RN
----------- ---------- ---------- -----------
50 09:30 10:30 1
50 10:30 11:45 1
50 11:45 12:15 1
50 14:00 14:40 2
50 14:40 15:10 2
答案 1 :(得分:0)
简单:
select sq.EMP_ID, sq.START_TIME, sq.END_TIME, sq.RN
from (
select e.*,
sum(case when xt.ID is not null then 0 else 1 end)
over(partition by e.emp_id order by e.start_time) + 1 as [RN],
xt.ID as [SameRange]
from @EMP_DETAILS e
left join @EMP_DETAILS xt on xt.EMP_ID = e.EMP_ID and xt.START_TIME = e.END_TIME
and xt.ID != e.ID
) sq
where sq.SameRange is not null;
排除不需要的行很简单,可以使用简单的left join
来完成。然而,对它们进行编号有点棘手。您需要SQL Server 2012或更高版本才能运行总计 - sum(...) over(order by ...)
- 才能正常工作。
如果您的表包含重复或零间隔(即同一行中的start_time = end_time
),则此处可能出现唯一可能的问题。最有可能的是,您需要使用子查询替换表,该子查询将提供不同的值。