Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 检查SQL中的日期范围_Sql Server_Tsql - Fatal编程技术网

Sql server 检查SQL中的日期范围

Sql server 检查SQL中的日期范围,sql-server,tsql,Sql Server,Tsql,根据我昨天提出的一个问题,我需要返回一系列笔记本电脑预定系统的可用日期。我想通过检查每个日期可能的插槽总数,然后减去已经预订的插槽数量,来填充一个用户可以预订插槽的可能可用日期表 逻辑如下: 一名技术人员每天可以制造3台笔记本电脑。 任何一天都可能有1名、2名或3名技术人员可用。 一张桌子放着预订的房间 我不想要一个包含所有可能日期的表格,我想动态计算 有关表格如下: 拖鞋 这包含已预订的房间 可用时间段 这用于计算给定日期的可用插槽总数 在这种情况下,我可以带回一个具有固定最大数量的日期列表

根据我昨天提出的一个问题,我需要返回一系列笔记本电脑预定系统的可用日期。我想通过检查每个日期可能的插槽总数,然后减去已经预订的插槽数量,来填充一个用户可以预订插槽的可能可用日期表

逻辑如下:

一名技术人员每天可以制造3台笔记本电脑。 任何一天都可能有1名、2名或3名技术人员可用。 一张桌子放着预订的房间 我不想要一个包含所有可能日期的表格,我想动态计算 有关表格如下:

拖鞋 这包含已预订的房间

可用时间段 这用于计算给定日期的可用插槽总数

在这种情况下,我可以带回一个具有固定最大数量的日期列表,即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
                       )