[MySQL] Verifica disponibilità camera

lorenzo84

Utente Attivo
22 Lug 2012
238
0
16
Buongiorno,
Non riesco a venirne a capo. Ho uno script per la visualizzazione e prenotazione delle camere libere e occupate che funziona bene. Adesso però devo verificare che ci siano camere libere per una prenotazione. Qualcuno mi aiuta?
Ho questa query da cui sono partito:

Codice:
SELECT * 
FROM prenotazioni
WHERE datain >=1412892000
AND dataout <=1413583200
questa però mi visualizza se esiste una qualsiasi prenotazione in questo range di date. Io in realtà devo verificare sia l'esistenza di una prenotazione ma allo stesso tempo dovrei verifica in base alle camere disponibili se queste sono occupate in queste date.

Pensavo di estrarre prima le stanze così:

Codice:
select * from stanze left join prenotazioni on stanze.id=prenotazioni.id_stanza where datain >=1412892000
AND dataout <=1413583200 group by stanza.id
e poi filtrarle con la condizione delle date con una query da query. Potrebbe funzionare?

Come posso fare?

Grazie a tutti
 
Ultima modifica:

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.039
146
63
PR
www.borgo-italia.it
ciao
io proverei con questo ragionamento:
ti richiedono una stanza da richiesta_in a richiesta_out
la stanza è libera se
richiesta_in è maggiore di prenotata_out o minore di prenota_in
e
richiesta_out è minore di prenotata_in o maggiore di prenota_out

quindi cercherei le stanze libere nell'intervallo di date da richiesta_in a richiesta_out con

Codice:
SELECT s.id_stanza FROM stanze AS s, prenotazioni AS p WHERE
(p.data_in > richiesta_in OR p.data_in > richiesta_out)
AND
(p.data_out < richiesta_out OR p.data_out > richiesta_in)
AND
s.id_stanza=p.id_stanza
prova, e se ho detto una ca...ta butta via tutto
 
Ultima modifica:

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.039
146
63
PR
www.borgo-italia.it
cio
scusa ho fatto un ragionamento complicato perche non ho pensato che nella richiesta è evidente che deve essere
richiesta_in < richiesta_out
cioè uno non può uscire sensa essere prima entrato, quindi la select si semplificherebbe un poco

Codice:
SELECT s.id_stanza FROM stanze AS s, prenotazioni AS p WHERE
(p.data_in > richiesta_out
OR
p.data_out < richiesta_in)
AND
s.id_stanza=p.id_stanza

sempre con quello che ho detto prima, eventualmente cestina
 

lorenzo84

Utente Attivo
22 Lug 2012
238
0
16
Ciao!!! grazie mille per la risposta. Sembrerebbe funzionare inserendo però maggiore uguale e minore uguale. Volevo però riuscire a farmi restituire anche l'elenco delle eventuali camere libere. come posso fare?
 

lorenzo84

Utente Attivo
22 Lug 2012
238
0
16
Ho provato a buttare giù due righe:

Codice:
$datain = strtotime($_POST['datain']);
$dataout=strtotime($_POST['dataout']);
echo $datain."<br/>";
echo $dataout."<br/>";

$sql_stanze="SELECT * FROM stanze AS s, prenotazioni AS p WHERE
(p.datain >= $datain
OR
p.dataout <= $dataout)
AND
s.id_stanza=p.stanza_id";
$risquerystanze=mysqli_query($conn,$sql_stanze);
$numrighesql_stanze=mysqli_num_rows($risquerystanze);
$row = mysqli_fetch_assoc($risquerystanze);

$arraystanze = array();
$arraystanzeoccupate = array();
//echo $row['id_stanza']."<br>";
while($row= mysqli_fetch_assoc($risquerystanze))
{

array_push($arraystanzeoccupate, $row['stanza_id']);


}

$stanze_libere="SELECT * FROM stanze";
$risstanze_libere=mysqli_query($conn,$stanze_libere);
$numrighesql_stanze=mysqli_num_rows($risstanze_libere);
while($rowstanze_libere = mysqli_fetch_assoc($risstanze_libere))
{
	array_push($arraystanze, $rowstanze_libere['id_stanza']);
}

$camerelibere= array_diff($arraystanze,$arraystanzeoccupate);
foreach($camerelibere as $id)

$rnd = rand(0,count($camerelibere)-1);

$sql_stanze="insert into prenotazioni (cliente_id,stanza_id,datain,dataout,stato)
VALUES (1,".$camerelibere[$rnd].",".$datain.",".$dataout.",1)";
$query_stanze=mysqli_query($conn,$sql_stanze);
if($query_stanze)
{
	echo "<a href='../index.php'>indietro</a>";
       //Inserimento prenotazione ok
}
else
{
	echo "errore";
}
Funziona sembra tutto ma quando arriva alle ultime 2 stanze disponibili mi dice:

Notice: Undefined offset: 0 in D:\xampp\htdocs\albergoprenotazione\lib\prenota.php on line 47

non capisco dove sbaglio...

Una volta che funziona dovrei poi essere in grado di raffinare la ricerca in base ad altri parametri presenti nelle stanze come adulti bambini ect.... no?

grazie
 

lorenzo84

Utente Attivo
22 Lug 2012
238
0
16
Eccoci... ci siamo quasi. Ho modificato la query mettendo invece che OR ho messo AND e in questo modo funziona. Con la OR mi dava sempre camere non disponibili anche con date diverse.
Puoi controllare se secondo te va bene?

ecco il codice:

PHP:
$datain = strtotime($_POST['datain']);
$dataout=strtotime($_POST['dataout']);
echo $datain."<br/>";
echo $dataout."<br/>";


$sql_stanze="SELECT * FROM stanze AS s, prenotazioni AS p WHERE
(p.datain >= $datain and p.dataout <= $dataout) AND s.id_stanza=p.stanza_id";
$risquerystanze=mysqli_query($conn,$sql_stanze);
$numrighesql_stanze=mysqli_num_rows($risquerystanze);

$i=0;
$arraystanzeoccupate=array();
while($row= mysqli_fetch_assoc($risquerystanze))
{
	array_push($arraystanzeoccupate, $row['stanza_id']);
}

$arraystanze = array();
$stanze="SELECT * FROM stanze";
$risstanze=mysqli_query($conn,$stanze);
$numrighesql=mysqli_num_rows($risstanze);
while($rowstanze = mysqli_fetch_assoc($risstanze))
{
	array_push($arraystanze, $rowstanze['id_stanza']);
}

$camereliberetmp= array_diff ($arraystanze,$arraystanzeoccupate);
$camerelibere=array();
foreach($camereliberetmp as $id)
{
	array_push($camerelibere, $id);	
}

$rnd = rand(0,count($camerelibere)-1);

if(count($camerelibere)>0)
{
	$sql_stanze="insert into prenotazioni (cliente_id,stanza_id,datain,dataout,stato)
	VALUES (1,".$camerelibere[$rnd].",".$datain.",".$dataout.",1)";
	$query_stanze=mysqli_query($conn,$sql_stanze);
	if($query_stanze)
	{
		echo "<a href='../index.php'>indietro</a>";
	}
	else
	{
		echo "errore";
	}
}
else
{
	echo "<br> Non ci sono camere disponibili";
}
Grazie
 
Ultima modifica di un moderatore:

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.039
146
63
PR
www.borgo-italia.it
ciao
per l'AND hai ragione.
poi visto così sembrebbe di si, non ho le tue tabelle per provarlo.
una cosa, non capisco quel
PHP:
$rnd = rand(0,count($camerelibere)-1);
assegni una libera a caso?
non ti converrebbe, quando hai gli id della canera libera visualizzari e con un url ad una pagina di inser prenotazione (o nella stassa) passare l'idi della stanza via GET?
poi per affinare la ricerca una domanda: nel form in cui inserisci le date in e out puoi indicare es il tipo singola o doppia e/o numero letti?
se si, sempre se hai pazienza ti faccio un esempio

p.s.
per gli scrip php usa l'apposito bcccode: PHP unlima iconcina a dx
 

lorenzo84

Utente Attivo
22 Lug 2012
238
0
16
Ciao. Per fare le prove assegno una camera casuale fra quelle disponibili. Diciamo che adesso devo creare una sorta di booking che data una data di arrivo, una di partenza, numero adulti, numero bambini e età dei bambini. Da li assegnerà una stanza provvisoria fino al pagamento..... E' ora che non saprei come andare avanti anche perchè dovrò integrarlo con booking e non sono riuscito a trovare le api di booking...
 

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.039
146
63
PR
www.borgo-italia.it
ciao
per booking non so dirti.
poi ti faccio un esempio di filtro perche poi ho delle "giornatine" e non so se faccio in tempo a risponderti
PHP:
<?php
//....
$datain = strtotime($_POST['datain']);
$dataout=strtotime($_POST['dataout']);
//con tipo intendo es. singola o doppia
$tipo=trim($_POST['tipo']);
$filtra="";
if ($filtra !=""){
	$filtra= " AND s.tipo='".$tipo."' ";
}
$sql_stanze="SELECT * FROM stanze AS s, prenotazioni AS p WHERE
(p.datain >= $datain AND p.dataout <= $dataout) AND s.id_stanza=p.stanza_id";
$sql_stanze .=$filtra;//concateni il filtro alla query sringa
/*
se non hai inputato il tipo la query stringa rimane quella sopra ($filtra è vuota)
se invece inputi il tipo es singola la query diventa
$sql_stanze="SELECT * FROM stanze AS s, prenotazioni AS p WHERE
(p.datain >= $datain and p.dataout <= $dataout) AND s.id_stanza=p.stanza_id AND s.tipo='singola'";
per cui ottieni, in questo caso, solo le stanze singole
*/
//.....
?>
 

lorenzo84

Utente Attivo
22 Lug 2012
238
0
16
Ciao!!! Grazie per le risposte.. Ora lo provo... Ma stavo pensando di estrarre le stanze disponibili e dare all'utente la scelta della camera in base al numero di adulti e bambini... Mi sembra la cosa migliore... no?
 

lorenzo84

Utente Attivo
22 Lug 2012
238
0
16
C'è un errore in questa query secondo me:

PHP:
SELECT * FROM stanze AS s, prenotazioni AS p WHERE
(p.datain >= $datain and p.dataout <= $dataout) AND s.id_stanza=p.stanza_id
Mettiamo il caso che ho una stanza numero 5 prenotata dal 21/10/2014 al 25/10/2014

Se io cerco una stanza dal 20/10/2014 al 26/10/2014 Mi esce anche questa numero 5 che in realtà è occupata fino al 25. quando in realtà nella notte fra il 24 e il 25 la stanza non sarebbe disponibile...

Ci sto perdendo il capo :D
 

lorenzo84

Utente Attivo
22 Lug 2012
238
0
16
Forse sono riuscito:

PHP:
SELECT * FROM stanze AS s, prenotazioni AS p WHERE
(p.datain >= $datain and p.dataout <= $dataout) OR (p.dataout BETWEEN
$datain and $dataout OR p.datain BETWEEN
$datain and $dataout)

AND s.id_stanza=p.stanza_id
Mi dici se secondo te va bene?
C'è ancora un problemino....
Se io cerco una stanza dal 22/10/2014 al 23/10/2014 e ho tutte le camere occupate per periodi uguali e ho tutte camere prenotate dal 20/10/2014 al 30/10/2014 mi esce fuori lo stesso...
 

marino51

Utente Attivo
28 Feb 2013
2.744
141
63
Lombardia
mi sembra che sei sulla buona strada, ma scusa se non mi sono fatto vivo prima, qualche impegno,
ti andrebbe di provare la mia soluzione sotto riportata ?
fai sapere, ciao
Marino
Codice:
SELECT * from stanze 
WHERE NOT EXISTS
(
SELECT stanza_id 
FROM prenotazioni
WHERE
(
( $datain >= datain AND $datain <= dataout ) 
OR
( $dataout >= datain AND $dataout <= dataout ) 
)
AND id_stanza=stanze.stanza_id
)
ps. attento alle variabili php rispetto ai nomi delle colonne, li ho girati
la soluzione con >= ti permette di togliere uguale se la camera viene liberata al mattino e impegnata al pomeriggio,
quindi il giorno di uscita/entrata è libero, ma questo lo puoi vedere in seguito
 

lorenzo84

Utente Attivo
22 Lug 2012
238
0
16
Ciao!!! grazie per la risposta... Ho provato a fare una prenotazione su una data che ho completo in tutte le camere ma restituisce tutte le camere se fossero vuote...
 

lorenzo84

Utente Attivo
22 Lug 2012
238
0
16
Eccomi... Ho modificato la query così:
PHP:
SELECT stanza_id FROM prenotazioni,stanze WHERE ( ( 1413151200 >= datain AND 1413151200 < dataout ) OR ( 1413237600 >= datain AND 1413237600 <= dataout ) ) AND stanza_id=stanze.id_stanza
Questo perchè verifico le camere occupate, mi estraggo l'elenco delle camere presenti e poi con array_diff() mi ritrovo gli ID delle camere libere già, in teoria, filtrare in base al numero di adulti e bambini...
 

marino51

Utente Attivo
28 Feb 2013
2.744
141
63
Lombardia
controlla come hai scritto la query, se non hai fatto copia/incolla,

ti posto il mio originale, garantendoti il funzionamento,
ciao
Marino
Codice:
declare @idhotel  as int;
declare @room     as int;
declare @date_in  as datetime;
declare @date_out as datetime;

set @idhotel  = 1;
set @date_in  = '2014/04/04';
set @date_out = '2014/04/17';

SELECT * from rooms 
WHERE NOT EXISTS
(
SELECT room 
FROM roomreservations
WHERE
(
( @date_in >= date_in AND @date_in <= date_out ) 
OR
( @date_out >= date_in AND @date_out <= date_out ) 
)
AND room=rooms.room
)
in coda a questa query (dopo l'ultima parentesi), puoi aggiungere le altre clausole where con la tipologia delle camere
 
Ultima modifica:

marino51

Utente Attivo
28 Feb 2013
2.744
141
63
Lombardia
Ciao! Questa query mi restituisce se ci sono camere vuote?
si mi sembra che fosse in linea con quello che volevi ...

la query seleziona dalle prenotazioni le camere occupate e le esclude dalla selezione delle camere (WHERE NOT EXISTS)

se poi vuoi, aggiungi in fondo dopo l'ultima parentesi le altre clausole 'AND' da applicare alla selezione della tabella stanze
ciao
Marino
 

lorenzo84

Utente Attivo
22 Lug 2012
238
0
16
ciao!!! Ho provato la query ma mi escono sempre le camere che siano libere o occupate.. dove sbaglio:

PHP:
SELECT * from stanze WHERE NOT EXISTS ( SELECT stanza_id FROM prenotazioni,stanze WHERE ( ( 1412892000 >= datain AND 1412892000 <= dataout ) OR ( 1412978400 >= datain AND 1412978400 <= dataout ) ) AND stanza_id=stanze.id_stanza )
Forse le tabelle mie e tue sono diverse... ?
 
Ultima modifica:

lorenzo84

Utente Attivo
22 Lug 2012
238
0
16
Ho fatto alcune prove:
PHP:
SELECT stanza_id FROM prenotazioni,stanze WHERE ( ( 1412892000 >= datain AND 1412892000 <= dataout ) OR ( 1412978400 >= datain AND 1412978400 <= dataout )
Con questa sembra funzionare. C'è un problema però:
La stanza 1 è libera mentre la stanza 2 e 3 sono occupare dal 10/10/2014 al 11/10/2014.

Se io richiedo una disponibilità per il periodo 08/10/2014 al 15/10/2014 Mi vengono date tutte le camere come libere quando in realtà dovrebbe essere libera solo la 1...