对于所有的示例,我假设BookedSchedules
中的开始和结束时间与StaffSchedules
的开始和结束时间完全匹配。
使用CTE,类似于问题:
我不建议使用这个查询,但它可能有所帮助,因为它类似于问题中的查询。它不太易读。
with NonBookingSlots as
(
select null as StaffId,StartdateTime,EndDateTime from Holidays
union all
select StaffId,StartdateTime,EndDateTime from BookedSchedules
)
select
StaffId, StartdateTime, EndDateTime
from
StaffSchedule
where
not exists(
select
1
from
NonBookingSlots
where
StaffSchedule.StaffId = isnull(NonBookingSlots.StaffId,StaffSchedule.StaffId)
and (
(
StaffSchedule.StartDateTime = NonBookingSlots.StartDateTime
and StaffSchedule.EndDateTime = NonBookingSlots.EndDateTime
) or (
StaffSchedule.StartDateTime < NonBookingSlots.EndDateTime
and StaffSchedule.EndDateTime > NonBookingSlots.StartDateTime
)
)
)
SQL Fiddle: http://sqlfiddle.com/#!3/9cbf4/14
没有使用 CTE:
我认为这个版本更易读。
select
StaffId, StartdateTime, EndDateTime
from
StaffSchedule
where
not exists(
select
1
from
BookedSchedules
where
StaffSchedule.StaffId = BookedSchedules.StaffId
and StaffSchedule.StartDateTime = BookedSchedules.StartDateTime
and StaffSchedule.EndDateTime = BookedSchedules.EndDateTime
) and not exists(
select
1
from
Holidays
where
StaffSchedule.StartDateTime < Holidays.EndDateTime
and StaffSchedule.EndDateTime > Holidays.StartDateTime
)
SQL Fiddle: http://sqlfiddle.com/#!3/9cbf4/15
使用外键 - 我的建议:
如果BookedSchedules
始终与StaffSchedule
匹配,您应该使用外键到StaffSchedule
,而不是在BookedSchedules
中复制开始和结束时间。这可以使查询更加简洁高效。
select
StaffId, StartdateTime, EndDateTime
from
StaffSchedule
where
not exists(
select
1
from
BookedSchedules
where
StaffSchedule.Id = BookedSchedules.StaffScheduleId
) and not exists(
select
1
from
Holidays
where
StaffSchedule.StartDateTime <= Holidays.EndDateTime
and StaffSchedule.EndDateTime >= Holidays.StartDateTime
)
SQL Fiddle: http://sqlfiddle.com/#!3/8a684/3