Principale utente con più risposte
Query con date

Domanda
-
Ciao a tutti
Un piccolo consiglio su come creare una query. Devo controllare se una camera non è prenotata in un dato periodo. Oltre a controllare tra i giorni prenotati, ho anche una tabella con i giorni in cui la camera non è disponibile.Come posso scrivere questa query?
Grazie mille
Risposte
-
salve,
ti giro la mia risposta che ti ho dato su ASPItalia, per completezza di informazione...
---
salve,
usualmente e' bella cosa indicare un minimo di DDL per fare in modo che non si debba inventare tutto lo scenario e partire da una base comune di riferimento...
detto cio', potresti ad esempio addivenire, in maniera moltro triviale, ad una ricerca simile aSET NOCOUNT ON; USE tempdb; GO CREATE TABLE dbo.Rooms ( Room varchar(10) NOT NULL PRIMARY KEY ); CREATE TABLE dbo.Booking ( Id int NOT NULL IDENTITY PRIMARY KEY, Room varchar(10) NOT NULL CONSTRAINT fk_Booking$has$Rooms FOREIGN KEY REFERENCES dbo.Rooms (Room) , Occupancy varchar(10) NOT NULL, Arrival date NOT NULL, Departure date NOT NULL ); CREATE TABLE dbo.Maintenance ( Id int NOT NULL IDENTITY PRIMARY KEY, Room varchar(10) NOT NULL CONSTRAINT fk_Maintenance$has$Rooms FOREIGN KEY REFERENCES dbo.Rooms (Room) , UnavailableDate date NOT NULL, Task varchar(20) NOT NULL ); GO INSERT INTO dbo.Rooms VALUES ('101'), ('102'), ('103'); INSERT INTO dbo.Booking VALUES ('101', 'A', '20130725', '20130728'), ('101', 'B', '20130729', '20130802'); INSERT INTO dbo.Maintenance VALUES ('101', '20130728', 'imp.elettrico'); GO DECLARE @Task varchar(10); DECLARE @bookFrom date, @bookTo date; SELECT @Task = '101', @bookFrom = '20130728', @bookTo = '20130729'; SELECT CONVERT(bit, 0) AS [IsMaintenaceTask], b.[Occupancy] AS [Occupancy/Task] FROM [dbo].[Booking] b WHERE @bookFrom BETWEEN b.[Arrival] AND CASE WHEN b.[Arrival] = b.[Departure] THEN b.[Departure] ELSE DATEADD(DAY, -1, b.[Departure]) END OR DATEADD(DAY, -1, @bookTo) BETWEEN b.[Arrival] AND CASE WHEN b.[Arrival] = b.[Departure] THEN b.[Departure] ELSE DATEADD(DAY, -1, b.[Departure]) END OR @bookFrom < b.[Arrival] AND @bookTo > b.[Departure] UNION SELECT CONVERT(bit, 1) AS [IsMaintenaceTask], h.[Task] AS [Occupancy/Task] FROM [dbo].[Maintenance] h WHERE h.[UnavailableDate] BETWEEN @bookFrom AND DATEADD(DAY, -1, @bookTo) GO DROP TABLE dbo.Booking, dbo.Maintenance, dbo.Rooms; --<-------- IsMaintenaceTask Occupancy/Task ---------------- -------------------- 1 imp.elettrico
dove per il periodo specificato la camera 101 non sara' disponibile a causa di un'attivita' di manutenzione... nel caso tu ricerchi la "disponibilta'" pura della camera, ti basterebbe negare il resultset in una clausola IF NOT EXISTS (..... )
detto cio', non "stravedo" per un'implementazione come questa, ma le tue indicazioni testuali mi hanno spinto su questa strada, ma probabilmente le ho mal interpretate....
come ben sai, un'occupazione puo' comportare dei cambi di camera, e quindi la tabella Booking non dovrebbe contenere l'attributo [Room], che dovrebbe essere parte di altra tabella referenziante la prenotazione in oggetto...
mi spiazza poi come sembri aver gestito le manutenzioni... per le occupazioni vere e proprie pari usare (a mio avviso correttamente) un time-frame, nell'esempio indicato dagli attributi [Arrival] e [Departure], mentre per le manutenzioni pari indicare il punto temporale giornaliero invece di un time-frame, quindi nel caso la camera 101 debba subire interventi all'impianto elettrico che ne comportino l'indisponibilita' per piu' giorni, mi pare di comprendere che saranno presenti "n" righe di indisponibilita', una per ogni giorno, con ridondanza nel caso in esame dell'attributo [Task] (ovviamente nel caso normalizzabile in altra tabella referenziata)... personalmente penso che comunque opterei per la finestra temporale e non per il momento puntuale come qui da me espresso...
ma probabilmente non ho ben interpretato le tue indicazioni...
salutihttp://www.hotelsole.com/asql/index.php - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/
- Proposto come risposta Emiliano Musso martedì 23 luglio 2013 12:34
- Contrassegnato come risposta SviPla mercoledì 24 luglio 2013 13:15
Tutte le risposte
-
-
salve,
ti giro la mia risposta che ti ho dato su ASPItalia, per completezza di informazione...
---
salve,
usualmente e' bella cosa indicare un minimo di DDL per fare in modo che non si debba inventare tutto lo scenario e partire da una base comune di riferimento...
detto cio', potresti ad esempio addivenire, in maniera moltro triviale, ad una ricerca simile aSET NOCOUNT ON; USE tempdb; GO CREATE TABLE dbo.Rooms ( Room varchar(10) NOT NULL PRIMARY KEY ); CREATE TABLE dbo.Booking ( Id int NOT NULL IDENTITY PRIMARY KEY, Room varchar(10) NOT NULL CONSTRAINT fk_Booking$has$Rooms FOREIGN KEY REFERENCES dbo.Rooms (Room) , Occupancy varchar(10) NOT NULL, Arrival date NOT NULL, Departure date NOT NULL ); CREATE TABLE dbo.Maintenance ( Id int NOT NULL IDENTITY PRIMARY KEY, Room varchar(10) NOT NULL CONSTRAINT fk_Maintenance$has$Rooms FOREIGN KEY REFERENCES dbo.Rooms (Room) , UnavailableDate date NOT NULL, Task varchar(20) NOT NULL ); GO INSERT INTO dbo.Rooms VALUES ('101'), ('102'), ('103'); INSERT INTO dbo.Booking VALUES ('101', 'A', '20130725', '20130728'), ('101', 'B', '20130729', '20130802'); INSERT INTO dbo.Maintenance VALUES ('101', '20130728', 'imp.elettrico'); GO DECLARE @Task varchar(10); DECLARE @bookFrom date, @bookTo date; SELECT @Task = '101', @bookFrom = '20130728', @bookTo = '20130729'; SELECT CONVERT(bit, 0) AS [IsMaintenaceTask], b.[Occupancy] AS [Occupancy/Task] FROM [dbo].[Booking] b WHERE @bookFrom BETWEEN b.[Arrival] AND CASE WHEN b.[Arrival] = b.[Departure] THEN b.[Departure] ELSE DATEADD(DAY, -1, b.[Departure]) END OR DATEADD(DAY, -1, @bookTo) BETWEEN b.[Arrival] AND CASE WHEN b.[Arrival] = b.[Departure] THEN b.[Departure] ELSE DATEADD(DAY, -1, b.[Departure]) END OR @bookFrom < b.[Arrival] AND @bookTo > b.[Departure] UNION SELECT CONVERT(bit, 1) AS [IsMaintenaceTask], h.[Task] AS [Occupancy/Task] FROM [dbo].[Maintenance] h WHERE h.[UnavailableDate] BETWEEN @bookFrom AND DATEADD(DAY, -1, @bookTo) GO DROP TABLE dbo.Booking, dbo.Maintenance, dbo.Rooms; --<-------- IsMaintenaceTask Occupancy/Task ---------------- -------------------- 1 imp.elettrico
dove per il periodo specificato la camera 101 non sara' disponibile a causa di un'attivita' di manutenzione... nel caso tu ricerchi la "disponibilta'" pura della camera, ti basterebbe negare il resultset in una clausola IF NOT EXISTS (..... )
detto cio', non "stravedo" per un'implementazione come questa, ma le tue indicazioni testuali mi hanno spinto su questa strada, ma probabilmente le ho mal interpretate....
come ben sai, un'occupazione puo' comportare dei cambi di camera, e quindi la tabella Booking non dovrebbe contenere l'attributo [Room], che dovrebbe essere parte di altra tabella referenziante la prenotazione in oggetto...
mi spiazza poi come sembri aver gestito le manutenzioni... per le occupazioni vere e proprie pari usare (a mio avviso correttamente) un time-frame, nell'esempio indicato dagli attributi [Arrival] e [Departure], mentre per le manutenzioni pari indicare il punto temporale giornaliero invece di un time-frame, quindi nel caso la camera 101 debba subire interventi all'impianto elettrico che ne comportino l'indisponibilita' per piu' giorni, mi pare di comprendere che saranno presenti "n" righe di indisponibilita', una per ogni giorno, con ridondanza nel caso in esame dell'attributo [Task] (ovviamente nel caso normalizzabile in altra tabella referenziata)... personalmente penso che comunque opterei per la finestra temporale e non per il momento puntuale come qui da me espresso...
ma probabilmente non ho ben interpretato le tue indicazioni...
salutihttp://www.hotelsole.com/asql/index.php - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/
- Proposto come risposta Emiliano Musso martedì 23 luglio 2013 12:34
- Contrassegnato come risposta SviPla mercoledì 24 luglio 2013 13:15
-
-