尝试根据Display next event date和SQL 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
从日期'20140115 00:00:00'到'20140116 11:59:59' - > 15t&第16天(2天)
从日期'20140120 00:00:00'到'20140125 11:59:59' - > 20日至25日(6天)
我需要删除介于上述日期之间的行
查询
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)
我的查询未过滤这些记录,并且由于LEFT JOIN而提供重复的条目。
答案 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)
这样就可以删除不需要的行和重复的行。
/丹尼尔