时间和日期冲突 - Sql Server

时间:2016-11-28 05:44:13

标签: sql-server

坚持一个项目。我在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

3 个答案:

答案 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