我有三张桌子。
问题是,如果我有三个预订:
所有预订都使用同一张桌子,有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]
给我: Bookingnr 1 =超额预订 预订2和3 =确定。
如果我删除预订3.我得到了预期的结果。问题是当3个或更多预订在同一张桌子上共享时间时。
我不想诉诸于在预订期间的所有可能时间做一个循环,并检查它是否超额预订。 查询经常被使用,可能是所有用户每分钟一次,并且一天可能有几百行。 我可以使用SQL或delphi数据集(但我宁愿在SQL中使用它)
修改1
它是更大的存储过程的一部分,可以完成所有其他类型的操作,因此它可以是一个函数。
我希望我不必处理最小间隔。 大多数使用该产品的客户都没有这个问题,因为他们不允许拆分表。而且我不希望查询对他们来说明显变慢。
答案 0 :(得分:2)
诀窍是扩展你的“预订”表在子查询/ derrived / CTE中,所以每个“间隔”(小时/半小时/分钟/等)是一行,然后你可以SUM - GROUP BY - HAVING SUM()&gt;限制。您可以使用Numbers表来扩展预订表。
使用代码编辑您的问题以构建表格,例如:
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
这里有一些问题:
--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
我不确定在超出座位限制时你想怎么处理。如果这些查询不够,请告诉我需要什么...另外,您使用的是哪个版本的SQL Server?