CTE给出以下结果
Name | StartDateTime | EndDateTime
--------------------+-------------------------+------------------------
Hair Massage | 2014-02-15 09:00:00.000 | 2014-02-15 10:00:00.000
Hair Massage | 2014-02-15 10:00:00.000 | 2014-02-15 11:00:00.000
(X)Hair Massage | 2014-02-23 09:00:00.000 | 2014-02-23 10:00:00.000
(X)Hair Cut | 2014-02-20 12:15:00.000 | 2014-02-20 13:00:00.000
Hair Cut | 2014-03-07 11:30:00.000 | 2014-03-07 12:15:00.000
我还有假期
Id | StartDateTime | EndDateTime
-------------+--------------------+-------------------
1 | 20140223 00:00:00 | 20140224 23:59:00
EventBooking
EventId | StartDateTime | EndDateTime
-------------+-------------------------+------------------------
1 | 2014-02-20 12:15:00.000 | 2014-02-20 13:00:00.000
我想从我的CTE中删除holidays and EventBooking
下的日期。
我的意思是从我的CTE中删除(X)
recods
RESULT=CTE- BookedSchedule-Holidays
with HoliDaysCte2 as
(
select StartdateTime,EndDateTime from Holidays
union all
select StartdateTime,EndDateTime from EventBooking
)
SELECT
Name,
StartDateTime,
EndDateTime
FROM CTE WHERE not exists (select 1
from HoliDaysCte2 h
where cast(a.RepeatEventDate as DATETIME) between
cast(h.startdatetime as DATETIME)
and cast(h.enddatetime as DATETIME)
)
这是我的SQL FIDDLE DEMO
答案 0 :(得分:4)
好的,假设这是你的架构
CREATE TABLE dbo.StaffSchedule
( ID INT IDENTITY(1, 1) NOT NULL,
Name Varchar(50),
StartdateTime DATETIME2 NOT NULL,
EndDateTime DATETIME2 NOT NULL
);
CREATE TABLE dbo.BookedSchedules
( ID INT IDENTITY(1, 1) NOT NULL,
StaffId INT,
StartdateTime DATETIME2 NOT NULL,
EndDateTime DATETIME2 NOT NULL
);
CREATE TABLE dbo.Holidays
( ID INT,
StartdateTime DATETIME2 NOT NULL,
EndDateTime DATETIME2 NOT NULL
);
INSERT dbo.StaffSchedule (Name, StartdateTime, EndDateTime)
VALUES
('Hair Massage','2014-02-15 09:00:00.000','2014-02-15 10:00:00.000'),
('Hair Massage','2014-02-15 10:00:00.000','2014-02-15 11:00:00.000'),
('(X)Hair Massage','2014-02-23 09:00:00.000','2014-02-23 10:00:00.000'),
('(X)Hair Cut','2014-02-20 12:15:00.000','2014-02-20 13:00:00.000'),
('Hair Cut','2014-03-07 11:30:00.000','2014-03-07 12:15:00.000');
INSERT dbo.BookedSchedules (StaffId, StartdateTime, EndDateTime)
VALUES
(1,'2014-02-20 12:15:00.000','2014-02-20 13:00:00.000');
INSERT dbo.Holidays (ID,StartdateTime, EndDateTime)
VALUES
(1,'20140223 00:00:00','20140224 23:59:00');
这是否解决了您的问题?
select * from StaffSchedule SS
where
not exists(
select * from NonBookingSlots NBS
where (dateadd(MICROSECOND,1,ss.StartdateTime)
between nbs.StartdateTime and nbs.EndDateTime)
or (dateadd(MICROSECOND,-1,ss.EndDateTime)
between nbs.StartdateTime and nbs.EndDateTime))
答案 1 :(得分:2)
好的尝试一下,
再创建一个cte,
,cte2 as
(
select * from @Holidays
union all
select BookingID,StartdateTime,EndDateTime from @EventBooking
)
然后像往常一样
AND not exists (select 1
from cte2 h
where cast(a.RepeatEventDate as date) between cast(h.startdatetime as date) and cast(h.enddatetime as date)
)
这是最新的(日期时间转换非常混乱,我刚开始 来自@Gordon查询。
AND not exists (select 1
from cte2 h
where cast(DATEADD(SECOND, DATEDIFF(SECOND, 0, StartTime), RepeatEventDate) as datetime) between cast(h.startdatetime as datetime) and cast(h.enddatetime as datetime)
)
答案 2 :(得分:2)
结果= CTE - BookedSchedule - 假期
将等于使用set theory subtract operation,在sql server中你可以使用Except(Oracle中的减号)。
select StaffId, StartdateTime,EndDateTime from StaffSchedule -- CTE
except
(select StaffId, StartdateTime,EndDateTime from BookedSchedules) -- BookedSchedule
except
(select StaffSchedule.StaffId, StaffSchedule.StartdateTime , StaffSchedule.EndDateTime
from StaffSchedule
inner join Holidays
on
cast(Holidays.StartdateTime As Date) = cast(StaffSchedule.StartdateTime As Date)
and
cast(Holidays.EndDateTime As Date) = cast(StaffSchedule.EndDateTime As Date)
) -- Holidays
;
Sqlfiddle demo
如果可以插入多日假期,例如:
INSERT dbo.Holidays (StartdateTime, EndDateTime)
VALUES
('2014-03-05 00:00:00.000', '2014-03-07 23:59:00.000');
使用以下查询提取员工假期将非常有用:
(select StaffSchedule.StaffId, StaffSchedule.StartdateTime , StaffSchedule.EndDateTime
from StaffSchedule
inner join Holidays
on
cast(Holidays.StartdateTime As Date) <= cast(StaffSchedule.StartdateTime As Date)
and
cast(Holidays.EndDateTime As Date) >= cast(StaffSchedule.EndDateTime As Date)
)
答案 3 :(得分:2)
请尝试:
select * From StaffSchedule
where ID not in(
select
ID
From StaffSchedule a inner join
(
select StartdateTime, EndDateTime From dbo.BookedSchedules
union all
select StartdateTime, EndDateTime From dbo.Holidays
)b on a.StartdateTime between b.StartdateTime and b.EndDateTime and
a.EndDateTime between b.StartdateTime and b.EndDateTime)
Chekck SQL Fiddle Demo
答案 4 :(得分:1)
这肯定会帮助你.....
WITH CTE AS (
SELECT
S.ID,
S.StaffId ,
S.StartdateTime,
S.EndDateTime,
H.StartdateTime 'HolydayStartDate' ,
H.EndDateTime AS 'HolydayDateDate',
B.StartdateTime AS 'BookedStartDate',
B.EndDateTime AS 'BookedEndDate'
FROM @StaffSchedule S
LEFT JOIN @Holidays H ON S.StartdateTime >= H.StartdateTime AND S.EndDateTime <= H.EndDateTime
LEFT JOIN @BookedSchedules B ON B.StaffId = S.StaffId AND B.StartdateTime = S.StartdateTime AND B.EndDateTime = S.EndDateTime
)
SELECT * FROM CTE
WHERE
HolydayStartDate IS NULL AND
HolydayDateDate IS NULL AND
BookedStartDate IS NULL AND
BookedEndDate IS NULL
答案 5 :(得分:1)
要检查您需要执行的重叠时段:
where p1.StartdateTime < p2.enddatetime
and p1.enddatetime > p2.startdatetime
根据您的需要,可能是&gt; = /&lt; =而不是&gt; /&lt;。
基于你的小提琴:
with NonBookingSlots as
(
select StartdateTime,EndDateTime from Holidays
union all
select StartdateTime,EndDateTime from BookedSchedules
)
SELECT
*
FROM StaffSchedule as ss
WHERE StaffId=1
AND not exists (select *
from NonBookingSlots h
where h.StartdateTime < ss.enddatetime
and h.enddatetime > ss.startdatetime
)
答案 6 :(得分:1)
我认为这对你有用 -
SELECT ss.* FROM StaffSchedule ss
LEFT JOIN BookedSchedules bs
ON (ss.StartdateTime BETWEEN bs.StartdateTime AND bs.EndDateTime)
AND (ss.EndDateTime BETWEEN bs.StartdateTime AND bs.EndDateTime)
LEFT JOIN Holidays h
ON (ss.StartdateTime BETWEEN h.StartdateTime AND h.EndDateTime)
AND (ss.EndDateTime BETWEEN h.StartdateTime AND h.EndDateTime)
WHERE bs.ID IS NULL AND h.StartdateTime IS NULL AND h.EndDateTime IS NULL