MySQL - нахождение времени перекрытия - PullRequest
6 голосов
/ 28 апреля 2010

У меня есть 2 таблицы в базе данных со следующими атрибутами:

Booking
=======
booking_id
booking_start
booking_end

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

Вторая таблица представляет собой ассоциативную сущность между «Резервированием» и «Ресурсом» (то есть 1 резервирование может содержать много ресурсов). Атрибуты booking_start и booking_end являются временными метками с указанием даты и времени.

Могу ли я узнать, как я могу узнать для каждого resource_id (resource_booked), совпадает ли дата / время с другими бронированиями с аналогичным resource_id?

Я рисовал ответ на бумаге, наглядно, чтобы увидеть, может ли он помочь мне визуализировать, как я могу решить эту проблему, и я получил это:

  1. Объединение двух таблиц (Booking, Booked_resource) в одну таблицу с четырьмя необходимыми атрибутами.
  2. Следуйте предложенному здесь ответу: Найти перекрывающиеся (дата / время) строки в одной таблице

Я сделал шаг 1, но шаг 2 оставляет меня в замешательстве!

Буду очень признателен за любую помощь в этом! Спасибо!

EDIT: Я читал ответ мистера Реншоу и пытался сделать его самостоятельно, чтобы понять, понял ли я и понял ли я концепцию:

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

Я думаю Я пытался создать 2 одинаковые таблицы и объединить их с помощью resource_id, найти записи с похожим идентификатором ресурса, но с другим значением booking_id, и посмотреть, находится ли date_start datetime одного (booking_id) между booking_start и booking_end другого (booking_id).

Это действительно грязно, и я даже не был уверен, что мой вопрос спрашивал, что я имел в виду, но каким-то чудом я получил тот же ответ, что и мистер Реншоу!

Ответы [ 2 ]

1 голос
/ 28 апреля 2010

РЕДАКТИРОВАТЬ: используя дополнительную информацию, теперь ограничено показом только тех бронирований, которые конфликтуют с более ранним бронированием.

Я думаю, что это добьется цели:

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

Вот как это было проверено:

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 голосов
/ 28 апреля 2010

Вау! Я бы никогда не подумал об этом .. Я не ожидал такой подробной помощи, большое спасибо за все усилия, которые вы вложили в это! Я пытаюсь понять и изучить ваш запрос:>

Таблица бронирований имеет еще один атрибут с именем creation_date, который показывает, когда было выполнено бронирование, и я надеялся показать только бронирование (с перекрытием во времени или столкновениями), которое было сделано позже. Так было бы:

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

Время между бронированием 1 и 2 перекрывается, и поскольку бронирование 2 было сделано на день позже бронирования 1, будет отображаться только бронирование 2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...