查找开始日期早于前一个结束日期的所有行

时间:2015-09-23 18:56:33

标签: sql sql-server tsql sql-server-2012

有没有办法根据用户撤回所有重叠日期时间的记录?

例如;

TableA具有以下行;

TrainerID            StartTime            EndTime
1234                 10-1-2015 08:30      10-1-2015 09:00 
1234                 10-1-2015 08:45      10-1-2015 09:15
1234                 10-1-2015 09:30      10-1-2015 10:00
2345                 10-1-2015 08:45      10-1-2015 09:15
2345                 10-1-2015 09:30      10-1-2015 10:00

我需要一个只能提取以下记录的查询,因为它的开始时间是在培训师的上一个结束时间之前(双重预订):

1234                 10-1-2015 08:45      10-1-2015 09:15

5 个答案:

答案 0 :(得分:2)

下面的EXIST代码应该给你答案。该代码确保冲突条目的开始时间在主列表条目的开始之前,而冲突的开始时间仍然在邮件列表条目的开始时间之后。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\DNSClient]
"EnableMulticast"=dword:00000000

这也可以用IN语句编写,但EXIST效率更高

答案 1 :(得分:1)

要删除重叠日期,您可以使用:

<强> Demo

CREATE TABLE #TABLEA( TrainerID INT, StartDate DATETIME, EndDate DATETIME);

INSERT INTO #TABLEA
SELECT 1234,  '10-1-2015 08:30', '10-1-2015 09:00'
UNION ALL SELECT 1234 , '10-1-2015 08:45',    '10-1-2015 09:15'
UNION ALL SELECT 1234 , '10-1-2015 09:30',    '10-1-2015 10:00'
UNION ALL SELECT 2345 , '10-1-2015 08:45',    '10-1-2015 09:15'
UNION ALL SELECT 2345 , '10-1-2015 09:30',    '10-1-2015 10:00';

SELECT
  D.TrainerID,
  [StartTime] = D.StartDate,
  [EndTime] = (SELECT MIN(E.EndDate)
               FROM #TABLEA E
               WHERE E.EndDate >= D.EndDate
                 AND E.TrainerID = D.TrainerID
                 AND NOT EXISTS (SELECT 1
                                 FROM #TABLEA E2
                                 WHERE E.StartDate < E2.StartDate
                                   AND E.EndDate > E2.StartDate
                                   AND E.TrainerID = E2.TrainerID)) 
FROM #TABLEA D
WHERE NOT EXISTS ( SELECT 1
                   FROM #TABLEA D2
                   WHERE D.StartDate < D2.EndDate
                     AND D.EndDate > D2.EndDate
                     AND D.TrainerID = D2.TrainerID);

答案 2 :(得分:1)

您可以使用下面的代码来获取所需的行,但是根据您下一个培训师ID(即2345)的逻辑行也将获得合格

  DECLARE @Trainers TABLE
(
    TrainerId INT,
    Start_Time datetime,
    End_Time datetime
)
INSERT INTO @Trainers VALUES 
(1234,'10-1-2015 08:30','10-1-2015 09:00 '),
(1234,'10-1-2015 08:45','10-1-2015 09:15'),
(1234,'10-1-2015 09:30','10-1-2015 10:00'),
(2345 ,' 10-1-2015 08:45','10-1-2015 09:15'),
(2345 ,' 10-1-2015 09:30 ',' 10-1-2015 10:00')


;WITH TrainersTemp AS
        (
        SELECT  *, ROW_NUMBER() OVER ( ORDER BY trainerid) AS rn
        FROM    @Trainers
        )
SELECT  CX.TrainerId, CX.Start_Time, CX.End_Time
FROM    TrainersTemp CX JOIN TrainersTemp CY
ON      CX.rn = CY.rn + 1
WHERE CY.End_Time < CX.Start_Time

Demo(SQL小提琴再次失败)

或者如果你想查看除故障之外的所有行,请使用下面的代码

 ;WITH TrainersTempAll AS
        (
        SELECT  *, ROW_NUMBER() OVER ( ORDER BY trainerid) AS rn
        FROM    @Trainers
        )
SELECT  CX.TrainerId, CX.Start_Time, CX.End_Time
FROM    TrainersTempAll CX JOIN TrainersTempAll CY
ON      CX.rn = CY.rn + 1

答案 3 :(得分:1)

首先,您应该按trainerId和Start_time排序。然后以正确的条件加入两个表。

尝试此查询:

;WITH TrainersTemp AS
(
    SELECT  *, ROW_NUMBER() OVER ( ORDER BY trainerid, Start_Time) AS row_num
    FROM    Trainers
)
select t2.* from TrainersTemp t1 
join TrainersTemp t2 on t1.TrainerId = t2.TrainerId and t1.row_num = t2.row_num-1
where t2.Start_Time<t1.End_Time

答案 4 :(得分:1)

在使用SQL Server 2012时,您可以使用LAG函数,这可能比自联接更有效。查询也变得非常简单。

对于每一行LAG,您会从上一行(EndTime分区)中获得TrainerID。然后,只需将当前行的StartTime与前一行的EndTime进行比较。

SQL Fiddle

WITH
CTE
AS
(
  SELECT
    TrainerID
    ,StartTime
    ,EndTime
    ,LAG(EndTime) OVER(PARTITION BY TrainerID ORDER BY StartTime) AS PrevEndTime
  FROM TableA
)
SELECT
    TrainerID
    ,StartTime
    ,EndTime
FROM CTE
WHERE StartTime < PrevEndTime
;

<强>结果:

| TrainerID |                 StartTime |                   EndTime |
|-----------|---------------------------|---------------------------|
|      1234 | October, 01 2015 08:45:00 | October, 01 2015 09:15:00 |