坚持一个项目。我在sql server中编写了这个代码,它找到了一个工作人员的重复日期匹配,但是当我试图将它扩展到缩小到时间范围相互重叠的时候,我就陷入困境。
所以有一张名为“Rosters'使用列' StaffID','日期','开始','结束'
SELECT
y.[Date],y.StaffID,y.Start,y.[End]
FROM Rosters y
INNER JOIN (SELECT
[Date],StaffID, COUNT(*) AS CountOf
FROM Rosters
GROUP BY [Date],StaffID
HAVING COUNT(*)>1)
dd ON y.[Date]=dd.[Date] and y.StaffID=dd.StaffID
它返回每个工作人员的所有重复日期,我希望添加逻辑 -
y.Start <= dd.[End] && dd.Start <= y.[End]
我现在这样做的方式有可能吗?任何帮助将不胜感激。
@TT。对不起,下面可能是一个更好的视觉解释 -
例如,这将是名册表
ID Date Start End
1 01/01/2000 8:00 12:00
1 01/01/2000 9:00 11:00
2 01/01/2000 10:00 14:00
2 01/01/2000 8:00 9:00
3 01/01/2000 14:00 18:00
3 02/02/2002 13:00 19:00
我试图返回下面的示例,因为它们是ID,日期和时间范围(开始 - 结束)冲突的唯一2行
ID Date Start End
1 01/01/2000 8:00 12:00
1 01/01/2000 9:00 11:00
答案 0 :(得分:2)
这是您需要将结果过滤到重叠时间范围的逻辑,但我认为这可以在没有找到重复项的中间步骤的情况下进行处理。如果您只是发布包含一些测试数据和所需输出的源表模式,您将得到更好的答案:
declare @t table (RowID int
,ID int
,DateValue date --\
,StartTime Time -- > Avoid using reserved words for your object names.
,EndTime Time --/
);
insert into @t values
(1,1, '01/01/2000', '8:00','12:00' )
,(2,1, '01/01/2000', '9:00','11:00' )
,(3,2, '01/01/2000', '10:00','14:00')
,(4,2, '01/01/2000', '8:00','9:00' )
,(5,3, '01/01/2000', '14:00','18:00')
,(6,3, '02/02/2002', '13:00','19:00');
select t1.*
from @t t1
inner join @t t2
on(t1.RowID <> t2.RowID -- If you don't have a unique ID for your rows, you will need to specify all columns so as no to match on the same row.
and t1.ID = t2.ID
and t1.DateValue = t2.DateValue
and t1.StartTime <= t2.EndTime
and t1.EndTime >= t2.StartTime
)
order by t1.RowID
答案 1 :(得分:1)
试试这个
with cte as
(
SELECT ROW_NUMBER() over (order by StaffID,Date,Start,End) as rno
,StaffID, Date, Start, End
FROM Rosters
)
select distinct t1.*
from cte t1
inner join cte t2
on(t1.rno <> t2.rno
and t1.StaffID = t2.StaffID
and t1.Date = t2.Date
and t1.Start <= t2.End
and t1.End >= t2.Start
)
order by t1.rno
在@ iamdave的答案中做了一些更改
答案 2 :(得分:0)
如果您使用SQL Server 2012,可以尝试以下脚本:
declare @roster table (StaffID int,[Date] date,[Start] Time,[End] Time);
insert into @roster values
(1, '01/01/2000', '9:00','11:00' )
,(1, '01/01/2000', '8:00','12:00' )
,(2, '01/01/2000', '10:00','14:00')
,(2, '01/01/2000', '8:00','9:00' )
,(3, '01/01/2000', '14:00','18:00')
,(3, '02/02/2002', '13:00','19:00');
SELECT t.StaffID,t.Date,t.Start,t.[End] FROM (
SELECT y.StaffID,y.Date,y.Start,y.[End]
,CASE WHEN y.[End] BETWEEN
LAG(y.Start)OVER(PARTITION BY y.StaffID,y.Date ORDER BY y.Start) AND LAG(y.[End])OVER(PARTITION BY y.StaffID,y.Date ORDER BY y.Start) THEN 1 ELSE 0 END
+CASE WHEN LEAD(y.[End])OVER(PARTITION BY y.StaffID,y.Date ORDER BY y.Start) BETWEEN y.Start AND y.[End] THEN 1 ELSE 0 END AS IsOverlap
,COUNT (0)OVER(PARTITION BY y.StaffID,y.Date) AS cnt
FROM @roster AS y
) t WHERE t.cnt>1 AND t.IsOverlap>0
StaffID Date Start End ----------- ---------- ---------------- ---------------- 1 2000-01-01 08:00:00.0000000 12:00:00.0000000 1 2000-01-01 09:00:00.0000000 11:00:00.0000000