Ich habe drei Tabellen.Suche nach Verfügbarkeit nach Zeit
- Tabelle (t), eine Ressource in meinem System. Es hat eine maximale Kapazität.
- Booking (b), eine Reservierung im System, hase es FromDatimeTime, ToDateTime und nrOfPeople
- BookedTable (bt), verbindet die Buchung mit Tisch und wie viele Sitze , die von dieser Buchung verwendet werden, eine Buchung kann mehr als eine Tabelle haben.
Das Problem ist, dass, wenn ich drei Buchungen:
- 4 Personen um 12:00 Uhr und um 14:00 Uhr verlassen comming.
- 4 Personen kommen um 12:00 und um 13:00 Uhr verlassen.
- 4 Personen kommen um 13:00 und um 14:00 Uhr verlassen.
Alle Buchungen mit der gleichen Tabelle mit 8 Plätzen. Ich möchte sehen, ob der Tisch "überbucht" ist.
Setup-Code
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
Einfache Testabfrage
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]
mich gibt: Bookingnr 1 = Buchung overbooked 2 und 3 = Ok.
Wenn ich Buchung entfernen 3. Ich bekomme das erwartete Ergebnis. Das Problem ist, wenn 3 oder mehr Buchungen die gleiche Zeit teilen.
Ich möchte nicht so etwas wie eine Schleife über alle möglichen Zeiten während der Buchung und überprüfen, ob es überbucht ist. Die Abfrage wird häufig verwendet, möglicherweise einmal pro Minute von allen Benutzern, und es kann einige hundert Zeilen für einen Tag geben. kann ich entweder SQL oder delphi Datenmenge verwenden (aber ich würde eher es in SQL tun)
Edit 1
Es ist ein Teil einer größeren gespeicherte Prozedur, die alle Arten von anderen Sachen tun, so Es könnte eine Funktion sein.
Ich würde es vorziehen, dass ich Minintervalle nicht behandeln würde. Die meisten Kunden, die das Produkt verwenden, haben dieses Problem nicht, da sie das Teilen einer Tabelle nicht zulassen. Und ich möchte nicht, dass die Abfrage für sie wesentlich langsamer ist.
In welchem Minintervall sind Sie tätig? Stunde, halbe Stunde oder Minute? –
Kann die Lösung ein auswählbarer gespeicherter Proc sein? Oder muss es eine einzelne SQL-Auswahl sein? –