2010-04-28 12 views
6

Tengo 2 tablas en la base de datos con los siguientes atributos:MySQL - se superpone Encontrar tiempo

Booking 
======= 
booking_id 
booking_start 
booking_end 

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

La segunda tabla es una entidad asociativa entre "Reserva" y "recursos" (es decir, 1 de reserva puede contener muchos recursos). Los atributos booking_start y booking_end son marcas de tiempo con fecha y hora en él.

¿Sé cómo podría averiguar cada resource_id (resource_booked) si la fecha/hora se superpone o choca con otras reservas de resource_id similar?

estaba garabateando la respuesta en papel, ilustrado, para ver si me puede ayudar a visualizar cómo podría solucionar esto y me dieron esto:

  1. Junto a las 2 tablas (reserva, Booked_resource) en una tabla con los 4 atributos necesarios.
  2. Siga la respuesta sugerida aquí: Find overlapping (date/time) rows within one table

lo hice, pero el paso 1 paso 2 se dejándome sorprendido!

¡Realmente agradecería cualquier ayuda en esto! ¡Gracias!

EDIT: que estaba leyendo la respuesta del Sr. Renshaw e intentó hacer una por mi cuenta para ver si entendí y me dieron el concepto:

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 

I que yo estaba tratando de crear 2 tablas idénticas y únelos con resource_id, busque registros con id de recurso similar pero diferente booking_id y vea si el booking_start datetime de uno (booking_id) está entre el booking_start y el booking_end de otro (booking_id).

Es realmente complicado y ni siquiera estaba seguro de si mi consulta me preguntaba qué era lo que tenía en mente, pero por algún milagro, obtuve la misma respuesta que el Sr. Renshaw.

Respuesta

1

EDITAR: utilizando información adicional, esto ahora está limitado a mostrar solo aquellas reservas que entran en conflicto con alguna reserva anterior.

creo que este WLL hacer el truco:

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 

Ésta es la forma en que se puso a prueba:

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

Por alguna razón, obtengo 'duplicados' de ciertos registros Como: * 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 ** Y otra línea a continuación: ** 21 | 2006-09-05 14: 12: 17.0 | 12 | 2006-08-31 13: 21: 25.0 | 23 ** – Cuppy

+0

Agregué otra cláusula WHERE que verifica si b1.creation_date> = b2.creation_date para que solo se muestren las reservas posteriores y ¡parece que funciona! ¡Gracias de nuevo! – Cuppy

0

Wow! Nunca hubiera pensado en eso ... No esperaba tanta asistencia detallada, ¡muchas gracias por todo el esfuerzo que han dedicado! Intento entender y aprender de su consulta:>

La tabla de reservas tiene otro atributo llamado creation_date que muestra cuándo se realizó la reserva y esperaba mostrar solo la reserva (con superposición en el tiempo o en choques) que fue hecho más tarde. Por lo tanto, sería:

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 

hay una superposición entre el tiempo de reserva 1 y 2 y desde la reserva 2 se realizó un día después de la reserva 1, sólo reserva 2 se muestra.

+0

¡Gracias! ¡Estaba teniendo problemas para tratar de formatear esa área! :> – Cuppy

+0

Sería mejor agregar información adicional como esta a su pregunta original editándola. Las discusiones pueden tener lugar usando la característica de comentario asociada con el queston –

+0

He editado mi respuesta para tener en cuenta esta información adicional –

Cuestiones relacionadas