忽略日期范围的记录

时间:2013-12-11 11:08:30

标签: sql sql-server sql-server-2008

尝试根据Display next event dateSQL Fiddle

构建定期事件系统

效果很好。我尝试将叶子计划与calander中的重复事件进行集成以对其进行过滤。意味着我需要忽略重复事件,如果它们属于计划的休假日期。

这是我的请假详细信息架构

CREATE TABLE dbo.Doctor
(
  DoctorID TINYINT IDENTITY(1, 1) NOT NULL,
  DoctorName VARCHAR(10) NOT NULL,
  CONSTRAINT PK_Doctor_DoctorID PRIMARY KEY (DoctorID)
)


INSERT Doctor(DoctorName) VALUES ('Dr John')

CREATE TABLE dbo.Leaves
(       LeaveID INT IDENTITY(1, 1) NOT NULL,
        DoctorID TINYINT NOT NULL,
        LeaveStartDateTime DATETIME2 NOT NULL,
        LeaveEndDateTime DATETIME2 NULL,

    CONSTRAINT PK_Leaves_LeaveID PRIMARY KEY (LeaveID),
    CONSTRAINT FK_Leaves_DoctorID FOREIGN KEY (DoctorID) REFERENCES dbo.Doctor (DoctorID)

);

Leave Data

  1. 从日期'20140115 00:00:00'到'20140116 11:59:59' - > 15t&第16天(2天)

  2. 从日期'20140120 00:00:00'到'20140125 11:59:59' - > 20日至25日(6天)

  3. 我需要删除介于上述日期之间的行

    查询

    WITH RepeatingEvents AS
    (   SELECT  d.DoctorName,
                l.LeaveStartDateTime,
                l.LeaveEndDateTime,
                e.Name,
                re.StartDateTime,
                re.EndDateTime,
                re.TimesToRepeat,
                RepeatEventDate = CAST(c.DateKey AS DATETIME) + CAST(re.StartTime AS DATETIME),
                RepeatNumber = ROW_NUMBER() OVER(PARTITION BY re.RepeatEventID ORDER BY c.Datekey)
        FROM    dbo.Event e
                INNER JOIN dbo.RepeatEvent re
                    ON e.EventID = re.EventID
                INNER JOIN dbo.RepeatType rt
                    ON rt.RepeatTypeID = re.RepeatTypeID
                INNER JOIN dbo.Calendar c
                    ON c.DateKey >= re.StartDate
                INNER JOIN dbo.RepeatDayOfWeek rdw
                    ON rdw.RepeatEventID = re.RepeatEventID
                    AND rdw.DayNumberOfWeek = c.DayNumberOfWeek
                INNER JOIN dbo.DoctorXEvent de ON e.EventID = de.EventID
                INNER JOIN dbo.Doctor d ON d.DoctorID = de.DoctorID
                LEFT JOIN dbo.Leaves l ON l.DoctorID = d.DoctorID 
        WHERE   rt.Name = 'Weekly'
    )
    SELECT  DoctorName, LeaveStartDateTime, LeaveEndDateTime,Name as EventName, StartDateTime, RepeatEventDate, RepeatNumber
    FROM    RepeatingEvents
    WHERE   (TimesToRepeat IS NULL OR RepeatNumber <= TimesToRepeat)
    AND     (EndDateTime IS NULL OR RepeatEventDate <= EndDateTime)
    AND     (RepeatEventDate NOT BETWEEN LeaveStartDateTime AND LeaveEndDateTime)
    

    SQL FIDDLE DEMO

    我的查询未过滤这些记录,并且由于LEFT JOIN而提供重复的条目。

1 个答案:

答案 0 :(得分:1)

左边连接到Leaves不起作用,因为连接中没有涉及日期。 用新谓词替换左连接以删除不需要的行:

AND NOT EXISTS 
    (SELECT 1 FROM Leaves l WHERE l.doctorId = d.doctorId 
    AND CAST(c.DateKey AS DATETIME) + CAST(re.StartTime AS DATETIME)  
    BETWEEN l.LeaveStartDateTime AND l.LeaveEndDateTime)

这样就可以删除不需要的行和重复的行。

/丹尼尔