Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.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 Server_Delphi_Datetime - Fatal编程技术网

Sql server 按时间查找可用性

Sql server 按时间查找可用性,sql-server,delphi,datetime,Sql Server,Delphi,Datetime,我有三张桌子 表(t),我的系统中的一个资源。 它有最大容量 预订(b),在 系统,它从DATIMETIME开始, 当今时代和人们的生活 BookedTable(bt),连接 用桌子预订,有多少座位 此预订使用的,a 预订可以有多张桌子 问题是,如果我有三个预订: 4人在12:00和 14点出发 4人在12:00和 13点出发 4人在13:00和 14点出发 所有预订使用同一张桌子,共有8个座位。 我想知道这张桌子是否“超额预定” 设置代码 CREATE TABLE Tables (

我有三张桌子

  • 表(t),我的系统中的一个资源。 它有最大容量
  • 预订(b),在 系统,它从DATIMETIME开始, 当今时代和人们的生活
  • BookedTable(bt),连接 用桌子预订,有多少座位 此预订使用的,a 预订可以有多张桌子
问题是,如果我有三个预订:

  • 4人在12:00和 14点出发
  • 4人在12:00和 13点出发
  • 4人在13:00和 14点出发
  • 所有预订使用同一张桌子,共有8个座位。 我想知道这张桌子是否“超额预定”

    设置代码

    CREATE TABLE Tables (
            TableNr INT, 
            Seats INT
            )
    GO 
    CREATE TABLE Booking 
        ( 
        BookingNr INT, 
        Time_From DATETIME, 
        Time_TO DATETIME, 
        Guests INT
        )
    GO 
    CREATE TABLE Table_Booking      
    (
     TableBookingId INT ,
     BookingNr INT ,
     TableNr INT ,
     GuestOnTable int 
    )
    GO 
    INSERT INTO [Tables] (  [TableNr],  [Seats]) VALUES ( 1, 8 ) 
    INSERT INTO [Tables] (  [TableNr],  [Seats]) VALUES ( 2, 4 ) 
    INSERT INTO [Tables] (  [TableNr],  [Seats]) VALUES ( 3, 4 ) 
    
    INSERT INTO [Booking] ([BookingNr],[Time_From],[Time_TO],[Guests]) VALUES ( /* BookingNr - INT */ 1,/* Time_From - DATETIME */ '2009-7-7 11:00',/* Time_TO - DATETIME */ '2009-7-7 13:00',/* Guests - INT */ 4 ) 
    INSERT INTO [Booking] ([BookingNr],[Time_From],[Time_TO],[Guests]) VALUES ( /* BookingNr - INT */ 2,/* Time_From - DATETIME */ '2009-7-7 11:00',/* Time_TO - DATETIME */ '2009-7-7 12:00',/* Guests - INT */ 4 ) 
    INSERT INTO [Booking] ([BookingNr],[Time_From],[Time_TO],[Guests]) VALUES ( /* BookingNr - INT */ 3,/* Time_From - DATETIME */ '2009-7-7 12:00',/* Time_TO - DATETIME */ '2009-7-7 13:00',/* Guests - INT */ 4 ) 
    
    
    INSERT INTO [Table_Booking] ([TableBookingId],[BookingNr],[TableNr], GuestOnTable) VALUES (/* TableBookingId - INT */ 1,    /* BookingNr - INT */ 1,/* TableNr - INT */ 1, 4 ) 
    INSERT INTO [Table_Booking] ([TableBookingId],[BookingNr],[TableNr], GuestOnTable) VALUES (/* TableBookingId - INT */ 2,    /* BookingNr - INT */ 2,/* TableNr - INT */ 1, 4 ) 
    INSERT INTO [Table_Booking] ([TableBookingId],[BookingNr],[TableNr], GuestOnTable) VALUES (/* TableBookingId - INT */ 3,    /* BookingNr - INT */ 3,/* TableNr - INT */ 1, 4 ) 
    
    GO 
    
    简单测试查询

    select Booking.BookingNr, [Booking].[Time_From], [Booking].[Time_TO], [Booking].[Guests], [Tables].TableNr  ,  
        CASE WHEN [Tables].[Seats] - 
        (  select sum(tbInner.[GuestOnTable]) from [Table_Booking] as tbInner    
            join [Booking] AS bInner on bInner.BookingNr = tbInner.BookingNr
            where (NOT ( Booking.Time_From>= bInner.[Time_To] OR bInner.[Time_From] >= Booking.Time_To ) )
             ) < 0 THEN 'OverBooked' ELSE 'Ok' END AS TableStatus
            from [Booking] 
            join [Table_Booking] on [Booking].[BookingNr] = [Table_Booking].[BookingNr]
            join [Tables] on [Tables].[TableNr] = [Table_Booking].[TableNr]
    
    选择Booking.BookingNr,[Booking].[Time\u From],[Booking].[Time\u TO],[Booking].[Guests],[Tables].TableNr,
    当[表格][座位]出现时的情况-
    (从[Table_Booking]中选择sum(tbInner.[GuestOnTable])作为tbInner
    在bInner.BookingNr=tbInner.BookingNr上以bInner的身份加入[预订]
    其中(不是(Booking.Time\u From>=bInner.[Time\u To]或bInner.[Time\u From]>=Booking.Time\u To))
    )<0然后“超额预订”,否则“正常”结束为TableStatus
    来自[预订]
    在[Booking].[BookingNr]=[Table\u Booking].[BookingNr]上加入[Table\u Booking]
    在[Tables].[TableNr]=[Table\u Booking].[TableNr]上加入[Tables]
    
    给我: 预订数量1=超额预订 预订2和3=可以

    如果我取消预订3。我得到了预期的结果。问题是当3个或更多预订共享同一张桌子上的时间时

    我不想求助于像在预订期间在所有可能的时间做一个循环,并检查是否超额预订。 查询经常被使用,所有用户可能每分钟使用一次,一天可能有几百行。 我可以使用SQL或delphi数据集(但我更愿意使用SQL)

    编辑1

    它是一个更大的存储过程的一部分,它可以处理所有其他的事情,所以它可以是一个函数

    我宁愿我不需要处理最小间隔。
    大多数使用该产品的客户没有这个问题,因为他们不允许拆分表。我不想让他们的查询速度明显变慢

    诀窍是在子查询/derrived/CTE中展开“Booking”表,因此每“interval”(小时/半小时/分钟/等)一行,然后您可以通过-HAVING SUM()>limit对-GROUP进行求和。您可以使用数字表展开bookings表

    使用代码编辑您的问题以生成表格,如:

    DECLARE @t table (col1......   )
    INSERT into @t values (......
    
    DECLARE @Booking  table(....
    INSERT into @Bookings) values (.....
    
    所以我可以尝试一个或两个查询,并尝试为您编写它

    编辑

    要使用我的以下查询,您需要创建此表:

    CREATE TABLE Numbers
    (Number int  NOT NULL,
        CONSTRAINT PK_Numbers PRIMARY KEY CLUSTERED (Number ASC)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    DECLARE @x int
    SET @x=0
    WHILE @x<8000
    BEGIN
        SET @x=@x+1
        INSERT INTO Numbers VALUES (@x)
    END
    
    创建表编号
    (数字int不为空,
    约束主键聚集(数字ASC)主键,并在[主]上(PAD_INDEX=OFF,STATISTICS_norecocomputer=OFF,IGNORE_DUP_KEY=OFF,ALLOW_ROW_LOCKS=ON,ALLOW_PAGE_LOCKS=ON)
    )在[小学]
    声明@x int
    设置为@x=0
    
    而@x您关心的最小间隔是多少?小时、半小时或分钟?解决方案可以是可选的存储过程吗?或者它必须是一个单一的SQL选择?这让我朝着正确的方向前进。我最终解决了这个问题。我所做的主要区别在于,我使用了一个带有可能时间的临时选项卡,而不是在实际查询中使用“DateAdd”。这是由于系统中的其他设计。
    --get one row per time "interval" (hour) per booking
    SELECT
        b.BookingNr, b.Time_From, b.Time_TO, b.Guests
            ,DATEADD(hh,Number-1,b.Time_From) AS ActualTime
        FROM Booking            b
            INNER JOIN Numbers  n ON DATEADD(hh,Number-1,b.Time_From)<=Time_TO
        ORDER BY 1,5
    
    --get one row per time "interval" (hour), combining each interval
    SELECT
        bt.TableNr, SUM(b.Guests) AS TotalGuests
            ,DATEADD(hh,Number-1,b.Time_From) AS ActualTime
        FROM Booking                   b
            INNER JOIN Numbers         n  ON DATEADD(hh,Number-1,b.Time_From)<=Time_TO
            INNER JOIN Table_Booking   bt ON b.BookingNr=bt.BookingNr
        GROUP BY bt.TableNr, DATEADD(hh,Number-1,b.Time_From)
        ORDER BY 3
    
    --get one row per time "interval" (hour), where the seat limit was exceeded
    SELECT
        bt.TableNr, SUM(b.Guests) AS TotalGuests
            ,DATEADD(hh,Number-1,b.Time_From) AS ActualTime
            ,t.Seats-SUM(b.Guests) AS SeatsAvailable
        FROM Booking                   b
            INNER JOIN Numbers         n  ON DATEADD(hh,Number-1,b.Time_From)<=Time_TO
            INNER JOIN Table_Booking   bt ON b.BookingNr=bt.BookingNr
            INNER JOIN Tables          t  ON bt.TableNr=t.TableNr
        GROUP BY bt.TableNr,t.Seats, DATEADD(hh,Number-1,b.Time_From)
        HAVING SUM(b.Guests)>t.Seats
        ORDER BY 3