2010-04-28 18 views
6

Ho 2 tabelle del database con i seguenti attributi:MySQL - Trovare il tempo si sovrappone

Booking 
======= 
booking_id 
booking_start 
booking_end 

resource_booked 
=============== 
booking_id 
resource_id 

La seconda tabella è un'entità associativa tra "prenotazione" e "risorse" (vale a dire, 1 prenotazione può contenere molti risorse). Gli attributi booking_start e booking_end sono timestamp con data e ora al suo interno.

Posso sapere come potrei essere in grado di scoprire per ogni resource_id (resource_booked) se la data/ora si sovrappone o si scontra con altre prenotazioni di resource_id simili?

stavo scarabocchiare la risposta su carta, pittoricamente, per vedere se poteva aiutarmi visualizzo come potrei risolvere questo e ho ottenuto questo:

  1. Unire i 2 tavoli (di prenotazione, Booked_resource) in una tabella con i 4 attributi necessari.
  2. Seguire la risposta suggerito qui: Find overlapping (date/time) rows within one table

ho fatto passo 1, ma il passaggio 2 sta lasciando me sconcertato!

Apprezzerei davvero qualsiasi aiuto su questo! Grazie!

EDIT: Stavo leggendo la risposta di Mr Renshaw e provato a fare uno da solo per vedere se ho capito e ho ottenuto il concetto:

SELECT 
    a.* 
FROM 
    (SELECT 
    b.creation_date, 
    b.booking_id, 
    r_b.resource_id, 
    b.booking_start, 
    b.booking_end 
    FROM Booking b 
    INNER JOIN resource_booked r_b ON b.booking_id = r_b.booking_id) as a, 
    (SELECT 
    b.booking_id, 
    r_b.resource_id, 
    b.booking_start, 
    b.booking_end 
    FROM Booking b INNER JOIN resource_booked r_b ON b.booking_id = r_b.booking_id) as 
WHERE 
    a.resource_id = b.resource_id 
AND 
    a.booking_id <> b.booking_id 
AND 
    a.booking_start BETWEEN b.booking_start AND b.booking_end 
AND 
    a.creation_date >= b.creation_date 

ho penso stavo cercando di creare 2 tabelle identiche e unisciti a resource_id, trova i record con ID di risorsa simile ma diverso booking_id e verifica se il tempo di prenotazione di un'ora di registrazione di uno (booking_id) è compreso tra il booking_start e il booking_end di un altro (booking_id).

È davvero caotico e non ero nemmeno sicuro se la mia domanda fosse quella che avevo in mente, ma per qualche miracolo ho avuto la stessa risposta di Mr Renshaw!

risposta

1

MODIFICA: utilizzando informazioni aggiuntive, questo è ora limitato a mostrare solo quelle prenotazioni che si scontrano con una prenotazione EARLIER.

penso che questo wll fare il trucco:

SELECT DISTINCT 
    b2.booking_id, -- The later booking 
    b2.booking_start, 
    b2.booking_end, 
    b2.creation_date, 
    rb1.resource_id, -- The resource over which the two bookings clash 
    b1.booking_id, -- The earlier booking 
    b1.booking_start, 
    b1.booking_end 
FROM resource_booked rb1 
    INNER JOIN booking b1 ON b1.booking_id = rb1.booking_id 
    INNER JOIN booking b2 ON b1.booking_id <> b2.booking_id 
     AND b2.booking_start BETWEEN b1.booking_start AND b1.booking_end 
    INNER JOIN resource_booked rb2 ON rb2.resource_id = rb1.resource_id 
     AND rb2.booking_id = b2.booking_id 

Ecco come è stato testato:

use tempdb 

drop table resource_booked 
drop table Booking 

create table Booking 
(
    booking_id int, 
    booking_start datetime, 
    booking_end datetime, 
    creation_date datetime 
) 

create table resource_booked 
(
    booking_id int, 
    resource_id int 
) 

insert Booking values (1, '1 january 2000', '1 march 2000', '1 january 2000') 
insert Booking values (2, '1 february 2000', '1 may 2000', '2 january 2000') 
insert Booking values (3, '1 april 2000', '1 june 2000', '3 january 2000') 
insert Booking values (4, '1 july 2000', '1 august 2000', '4 january 2000') 

insert resource_booked values (1, 1) 
insert resource_booked values (2, 1) 
insert resource_booked values (3, 1) 
insert resource_booked values (4, 1) 
insert resource_booked values (1, 2) 
insert resource_booked values (3, 2) 
+0

Per qualche motivo, sto ottenendo "duplicati" di determinati record Come: * b2.booking_id | b2.creation_date | rb1.resource_id | b1.creation_date | b1.booking_id * ** 23 | 2006-08-31 13: 21: 25.0 | 12 | 2006-09-05 14: 12: 17.0 | 21 ** E un'altra riga in basso: ** 21 | 2006-09-05 14: 12: 17.0 | 12 | 2006-08-31 13: 21: 25.0 | 23 ** – Cuppy

+0

Ho aggiunto un'altra clausola WHERE che controlla se b1.creation_date> = b2.creation_date in modo che solo le prenotazioni effettuate in seguito vengano visualizzate e sembra funzionare! Grazie ancora! – Cuppy

0

Wow! Non avrei mai pensato a questo .. Non mi aspettavo un'assistenza così dettagliata, grazie mille per tutto lo sforzo che ci hai messo! Sto cercando di capire e imparare dalla tua query:>

La tabella delle prenotazioni ha un altro attributo chiamato creation_date che mostra quando è stata effettuata la prenotazione e speravo di mostrare solo la prenotazione (con sovrapposizione in tempo o scontri) che è stato fatto più tardi Quindi sarebbe:

Booking 1 
========= 
creation_date - 2000-01-01 13:00:00 
booking_start - 2000-02-24 12:00:00 
booking_end - 2000-02-24 14:00:00 

Booking 2 
========= 
creation_date - 2000-01-02 15:00:00 
booking_start - 2000-02-24 13:00:00 
booking_end - 2000-02-24 15:00:00 

C'è una sovrapposizione temporale tra prenotazione 1 e 2 e dal 2 prenotazione è stata fatta il giorno dopo che prenotare 1, solo prenotando 2 sarebbe mostrato.

+0

Grazie! Stavo riscontrando problemi nel tentativo di formattare quell'area! :> – Cuppy

+0

Sarebbe meglio aggiungere ulteriori informazioni come questa alla tua domanda originale modificandola. Le discussioni possono avvenire uing la funzione di commento associato al queston –

+0

Ho modificato la mia risposta per tener conto di queste informazioni supplementari –

Problemi correlati