2014-08-28 11 views
5

Chiedo al tuo aiuto di scrivere una query per verificare la disponibilità di una stanza all'interno di MySql. Attualmente ho questo tipo di tabella:Trova le sovrapposizioni delle prenotazioni per verificare le date disponibilità

ROOM | FROM |  TO 
----------------------------- 
    101 | 2014-08-09 | 2014-08-14 
    102 | 2014-08-09 | 2014-08-14 
    ...   ...  ... 

Così ho la camera 101 prenotato da 2014/09/08 a 14-08-2014, la mia domanda per controllare la disponibilità è assomigliare =

SELECT order_id FROM booking 
WHERE `ROOM` = '101' 
AND (`FROM` BETWEEN '2014-08-08' AND '2014-08-20') 
AND (`TO` BETWEEN '2014-08-08' AND '2014-08-20') 

nell'esempio sopra io controllerà la disponibilità nelle date tra

What i trying to archive is this 
Order --------09++++++++++13-------------- 
Check1 -----08+++++++++++++++++++++++++17-- Not availble 
Check2 -----------------12+++++++++++++17-- Not availble 
Check3 -----------10----------------------- Not availble 
Check4 -----------10+11-------------------- Not availble 
Check5 -----------------------14+++++++17-- Available 
Check6 --07++++09-------------------------- Not availble 
Check7 --------------------------15-------- Availble 


SCALE 6-07-08-09-10-11-12-13-14-15-16-17-18-19... 

Devo controllare se la stanza è disponibile. Quindi se ottengo qualche risultato da quella query significa che la stanza è già prenotata ... se ottengo niente esattamente l'opposto ...

+1

nomi di colonne di controllo. Nella query u scrivi in ​​lettere minuscole. –

+0

Ahahah. Puoi aiutarmi con questa domanda, ora? – KARC

+0

Puoi essere chiaro sulla tua domanda –

risposta

4

In primo luogo, generalizziamo un algoritmo per come verificare una sovrapposizione tra gli intervalli e [c,d]. Notare le parentesi quadre su quegli intervalli, il che significa un intervallo inclusivo. Possiamo usare questa logica per verificare una sovrapposizione di intervalli:

a <= d and b >= c 

Se questa condizione è vera, allora abbiamo una sovrapposizione.

Quindi, per applicare questo algoritmo per SQL, si potrebbe fare qualcosa di simile:

a = 2014-08-08 
b = 2014-08-20 
c = FROM 
d = TO 
SELECT order_id FROM booking 
WHERE NOT EXISTS (
    SELECT * FROM booking 
     WHERE ROOM = '101' 
     AND '2014-08-08' <= `TO` 
     AND '2014-08-20' >= `FROM` 
) 
AND ROOM = '101' 

L'altro problema con il vostro approccio è che si sta verificando, per vedere se una camera è disponibile, e l'assunzione qui è che se la stanza è disponibile, allora la prenoterai con un'altra istruzione SQL. Questo è un approccio problematico, perché c'è la possibilità che tu possa raddoppiare la prenotazione di una stanza. Considera la possibilità che due processi controllino la disponibilità delle stanze allo stesso tempo (o vicino allo stesso). O un altro esempio sarebbe se questo codice fosse parte di una transazione che non era stata ancora commessa. L'altro processo non vedrebbe il risultato impegnato e, quindi, raddoppierà la stanza.

Per rimediare a questo approccio errato, è necessario bloccare la riga della stanza prima di verificarne la disponibilità. Supponendo di avere qualche altra tabella chiamata CAMERA, si potrebbe bloccare la fila con un 'FOR UPDATE' affermazione:

SELECT * FROM `ROOM` WHERE ROOM = '101' FOR UPDATE 

Il "aggiornamenti" si bloccherà quella riga stanza, che impedirà un altro processo da controllare che spazio per disponibilità fino al completamento della transazione. Dopo aver bloccato la riga, è possibile eseguire il controllo di sovrapposizione. Quindi, elimini il doppio problema di prenotazione.

Ulteriori informazioni su 'FOR UPDATE' sono disponibili su here.

+0

come è correlato a 'order_id' la sottoquery? ... non selezionerebbe tutto o nessun order_id a seconda del risultato della subquery? – FuzzyTree

+0

@FuzzyTree - Non capisco veramente order_id nel contesto dei dati dell'OP. Stavo solo usando la loro query originale come base. La domanda dell'op – dcp

+0

non è chiara, ma penso che potrebbero cercare 'select not exists (...)' e che 'order_id' è l'id di una prenotazione – FuzzyTree

0

Se si desidera verificare se la stanza è disponibile per l'intero periodo, guarda per le prenotazioni esistenti che si sovrappongono con periodo in questione:

SELECT order_id FROM booking 
WHERE `ROOM` = '101' 
AND `FROM` <= '2014-08-20' 
AND `TO` >= 2014-08-08' 

Se la query restituisce le righe, si ha un conflitto prenotazione e la camera non è disponibile.

0

per verificare se una stanza proposte prenotazione conflitti con (sovrapposizioni) uno già esistente, si desidera qualcosa di simile:

select count(*) as num_conflicts 
from booking 
where room = ?proposed_room 
    and (from <= ?proposed_to) 
    and (to >= ?proposed_from); 

che conta un conflitto quando in qualsiasi giorno della prenotazione proposto è già assegnato a un altro di prenotazione .

+0

Ovviamente, il '? Proposal_ *' non è SQL, ma è lì che usereste i parametri in una dichiarazione preparata in qualche lingua host. –

+0

Grazie al tuo codice funziona ma non ho bisogno di un conteggio ma l'ID ordini: D – KARC

+0

seleziona "order_id' dalla prenotazione dove' ROOM' = '101' e ('FROM' <= '2014-08-10') e (' TO> = '2014-08-15')> non mostra il record (fallisce) – KARC

Problemi correlati