對於我所做的假定所有的例子,在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小提琴: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小提琴: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小提琴:http://sqlfiddle.com/#!3/8a684/3
+1爲一個完整的問題 – Kermit
能否在工作人員的安排被部分預訂或者只客滿(如與您的所有示例數據的情況下)? –
@ShWiVeL,其全套 – Billa