Sql server 检查SQL中的日期范围
根据我昨天提出的一个问题,我需要返回一系列笔记本电脑预定系统的可用日期。我想通过检查每个日期可能的插槽总数,然后减去已经预订的插槽数量,来填充一个用户可以预订插槽的可能可用日期表 逻辑如下: 一名技术人员每天可以制造3台笔记本电脑。 任何一天都可能有1名、2名或3名技术人员可用。 一张桌子放着预订的房间 我不想要一个包含所有可能日期的表格,我想动态计算 有关表格如下: 拖鞋 这包含已预订的房间 可用时间段 这用于计算给定日期的可用插槽总数 在这种情况下,我可以带回一个具有固定最大数量的日期列表,即3个插槽:Sql server 检查SQL中的日期范围,sql-server,tsql,Sql Server,Tsql,根据我昨天提出的一个问题,我需要返回一系列笔记本电脑预定系统的可用日期。我想通过检查每个日期可能的插槽总数,然后减去已经预订的插槽数量,来填充一个用户可以预订插槽的可能可用日期表 逻辑如下: 一名技术人员每天可以制造3台笔记本电脑。 任何一天都可能有1名、2名或3名技术人员可用。 一张桌子放着预订的房间 我不想要一个包含所有可能日期的表格,我想动态计算 有关表格如下: 拖鞋 这包含已预订的房间 可用时间段 这用于计算给定日期的可用插槽总数 在这种情况下,我可以带回一个具有固定最大数量的日期列表
DECLARE @startDate DATE
DECLARE @endDate DATE
SET @startDate = GETDATE()
SET @endDate = DATEADD(m,3,@startDate)
;
WITH dates(Date) AS
(
SELECT @startdate as Date
UNION ALL
SELECT DATEADD(d,1,[Date])
FROM dates
WHERE DATE < @enddate
)
SELECT Date
FROM dates
EXCEPT
SELECT date
FROM tl_sb_booking
GROUP BY date
HAVING COUNT(date) >= 3
然而,最大值并不总是3,它每天都在变化
我可以找到给定日期的最大可能插槽:
DECLARE @myDate DATETIME = '2013-06-22'
SELECT SUM(laptopsPerDay) AS totalSlots
FROM tl_sb_technicianAvailability
WHERE startDate <= @myDate AND endDate >= @myDate
AND availabiltyStateID=3
它将为2013-06-22年带来6个可用插槽总数。availabilityStateID字段用于存储可用/不可用等
所以,我一直坚持的一点是将两者结合起来
我想要的是每个可能的日期,如果已经预订的插槽数量少于当天可能的插槽数量,请将其添加到正在返回的表中,否则不要。首先,尽管您只生成一个小列表,最好避免 为此,我将使用system table Master..spt_值作为数字的顺序列表,但是如果您担心使用未记录的系统表,那么在上面的链接中还有其他方法 我要做的第一件事是每天将技师的可用日期分成一行,这将允许仅可用于部分所需peiod的技术人员,例如,如果您想在6月18日至6月26日期间进行查询,则可从表中的sceen快照中使用您发布的查询显示没有任何技术人员可用:
SELECT Date = DATEADD(DAY, spt.Number, ta.StartDate),
ta.TechnicianID,
ta.LapTopsPerDay
FROM tl_sb_technicianAvailability ta
INNER JOIN Master..spt_values spt
ON spt.Type = 'P'
AND spt.Number BETWEEN 0 AND DATEDIFF(DAY, ta.startDate, ta.EndDate)
This would simply turn:
TechnicianID StartDate EndDate LapTopsPerDay
1 20130620 20130624 3
进入
然后,您可以将此列表限制在所需的日期范围内,并将笔记本电脑总数加起来,因为在技术层面上不需要这样做:
WITH ExplodedAvailability AS
( SELECT Date = DATEADD(DAY, spt.Number, ta.StartDate),
ta.TechnicianID,
ta.LapTopsPerDay
FROM tl_sb_technicianAvailability ta
INNER JOIN Master..spt_values spt
ON spt.Type = 'P'
AND spt.Number BETWEEN 0 AND DATEDIFF(DAY, ta.startDate, ta.EndDate)
)
SELECT Date, TotalLaptops = SUM(LapTopsPerDay)
FROM ExplodedAvailability
WHERE Date >= @StartDate
AND Date < @EndDate
GROUP BY Date;
如果这对任何人都有用,我最终就是这样做的:
DECLARE @startDate DATE
DECLARE @endDate DATE
SET @startDate = GETDATE()
SET @endDate = DATEADD(m,3,@startDate)
;
WITH dates(currentDate) AS
(
SELECT @startdate as currentDate
UNION ALL
SELECT DATEADD(d,1,[currentDate])
FROM dates
WHERE currentDate < @enddate
)
SELECT currentDate
FROM dates
WHERE /* slots booked for date */
(
SELECT count([date])
FROM tl_sb_booking
where [date] = currentDate
)
<
/* total slots available */
(
SELECT SUM(laptopsPerDay) AS totalSlots
FROM tl_sb_technicianAvailability
WHERE startDate <= currentDate AND endDate >= currentDate
AND availabiltyStateID=3
)
WITH ExplodedAvailability AS
( SELECT Date = DATEADD(DAY, spt.Number, ta.StartDate),
ta.TechnicianID,
ta.LapTopsPerDay
FROM tl_sb_technicianAvailability ta
INNER JOIN Master..spt_values spt
ON spt.Type = 'P'
AND spt.Number BETWEEN 0 AND DATEDIFF(DAY, ta.startDate, ta.EndDate)
), Availability AS
( SELECT Date, TotalLaptops = SUM(LapTopsPerDay)
FROM ExplodedAvailability
WHERE Date >= @StartDate
AND Date < @EndDate
GROUP BY Date
), Bookings AS
( SELECT Date, SlotsBooked = COUNT(*)
FROM tl_sb_booking
GROUP BY Date
)
SELECT Availability.Date,
Availability.TotalLaptops,
RemainingSlots = Availability.TotalLaptops - ISNULL(Bookings.SlotsBooked, 0)
FROM Availability
LEFT JOIN Bookings
ON Bookings.Date = Availability.Date;
DECLARE @UserID INT = 1;
WITH ExplodedAvailability AS
( SELECT Date = DATEADD(DAY, spt.Number, ta.StartDate),
ta.TechnicianID,
ta.LapTopsPerDay
FROM tl_sb_technicianAvailability ta
INNER JOIN Master..spt_values spt
ON spt.Type = 'P'
AND spt.Number BETWEEN 0 AND DATEDIFF(DAY, ta.startDate, ta.EndDate)
), Availability AS
( SELECT Date, TotalLaptops = SUM(LapTopsPerDay)
FROM ExplodedAvailability
WHERE Date >= CAST(GETDATE() AS DATE)
GROUP BY Date
), Bookings AS
( SELECT Date, SlotsBooked = COUNT(*)
FROM tl_sb_booking
GROUP BY Date
)
INSERT tl_sb_slotBooking (UserID, Date)
SELECT @UserID, MIN(Availability.Date)
FROM Availability
LEFT JOIN Bookings
ON Bookings.Date = Availability.Date
WHERE Availability.TotalLaptops > ISNULL(Bookings.SlotsBooked, 0)
DECLARE @startDate DATE
DECLARE @endDate DATE
SET @startDate = GETDATE()
SET @endDate = DATEADD(m,3,@startDate)
;
WITH dates(currentDate) AS
(
SELECT @startdate as currentDate
UNION ALL
SELECT DATEADD(d,1,[currentDate])
FROM dates
WHERE currentDate < @enddate
)
SELECT currentDate
FROM dates
WHERE /* slots booked for date */
(
SELECT count([date])
FROM tl_sb_booking
where [date] = currentDate
)
<
/* total slots available */
(
SELECT SUM(laptopsPerDay) AS totalSlots
FROM tl_sb_technicianAvailability
WHERE startDate <= currentDate AND endDate >= currentDate
AND availabiltyStateID=3
)