开发者

help in forming mysql query to find free(available) venues/resources for a give date range

开发者 https://www.devze.com 2022-12-16 07:17 出处:网络
I have tables & data like this: venues table contains : id +----+---------+ id | name| +----+---------+

I have tables & data like this:

venues table contains : id

+----+---------+ | id | name | +----+---------+ | 1 | venue 1 | | 2 | venue 2 | --------------- event_dates : id, event_id, event_from_datetime, event_to_datetime, venue_id +----+----------+---------------------+---------------------+----------+ | id | event_id | event_from_datetime | event_to_datetime | venue_id | +----+----------+---------------------+---------------------+----------+ | 1 | 1 | 2009-12-05 00:00:00 | 2009-12-07 00:00:00 | 1 | | 2 | 1 | 2009-12-09 00:00:00 | 2009-12-12 00:00:00 | 1 | | 3 | 1 | 2009-12-15 00:00:00 | 2009-12-20 00:00:00 | 2 | +----+----------+---------------------+---------------------+----------+

This is my requirement: I want venues that will be free on 2009-12-06 00:00:00 i.e.

I should get

|venue_id|

|2 |

Currently I'm having the following query,

select ven.id , evtdt.event_from_datetime, evtdt.event_to_datetime 
from venues ven 
left join event_dates evtdt 
on (ven.id=evtdt.venue_id) 
where evtdt.venue_id is null 
or not ('2009-12-06 00:00:00' between evtdt.event_from_datetime 
                                  and evtdt.event_to_datetime);
+----+---------------------+---------------------+
| id | event_from_datetime | event_to_datetime   |
+----+---------------------+---------------------+
|  1 | 2009-12-09 00:00:00 | 2009-开发者_运维百科12-12 00:00:00 |
|  2 | 2009-12-15 00:00:00 | 2009-12-20 00:00:00 |
|  3 | NULL                | NULL                |
|  5 | NULL                | NULL                |
+----+---------------------+---------------------+

If you note the results, its not including venue id 1 where date is in between 2009-12-06 00:00:00 but showing other bookings. Please help me correct this query.

Thanks in advance.


SELECT  *
FROM    venue v
WHERE   NOT EXISTS
        (
        SELECT  NULL
        FROM    event_dates ed
        WHERE   ed.venue_id = v.id
                AND '2009-12-06 00:00:00' BETWEEN ed.event_from_datetime AND ed.event_to_datetime
        )


or not ('2009-12-06 00:00:00' between evtdt.event_from_datetime 
                              and evtdt.event_to_datetime);

12/6/2009 is between 12/5/09 and 12/7/09... that's why venue_id 1 is being excluded... what is it you're trying to extract from the data exactly?

The join query you've constructed says, take the venues table and for each row of it that has a matching venue_id make a copy of the venue table row and append the matching row. So if you just did:

select * 
  from venues ven 
  left join event_dates evtdt 
  on (ven.id=evtdt.venue_id);

It would yield:

+----+---------+------+----------+---------------------+---------------------+----------+
| id | name    | id   | event_id | event_from_datetime | event_to_datetime   | venue_id |
+----+---------+------+----------+---------------------+---------------------+----------+
|  1 | venue 1 |    1 |        1 | 2009-12-05 00:00:00 | 2009-12-07 00:00:00 |        1 |
|  1 | venue 1 |    2 |        1 | 2009-12-09 00:00:00 | 2009-12-12 00:00:00 |        1 |
|  2 | venue 2 |    3 |        1 | 2009-12-15 00:00:00 | 2009-12-20 00:00:00 |        2 |
+----+---------+------+----------+---------------------+---------------------+----------+

If you then added your condition, which states the date of interest is not between the from and to date of the event, the query looks like:

select * 
  from venues ven 
  left join event_dates evtdt 
  on (ven.id=evtdt.venue_id) 
  where not ('2009-12-06' between evtdt.event_from_datetime and evtdt.event_to_datetime)

Which yields a result of:

+----+---------+------+----------+---------------------+---------------------+----------+
| id | name    | id   | event_id | event_from_datetime | event_to_datetime   | venue_id |
+----+---------+------+----------+---------------------+---------------------+----------+
|  1 | venue 1 |    2 |        1 | 2009-12-09 00:00:00 | 2009-12-12 00:00:00 |        1 |
|  2 | venue 2 |    3 |        1 | 2009-12-15 00:00:00 | 2009-12-20 00:00:00 |        2 |
+----+---------+------+----------+---------------------+---------------------+----------+

These are my actual experimental results with your data in MySQL.

If you want to get the venue_ids that are free on the proposed date then you would write something like:

  select ven.id, SUM('2009-12-06' between evtdt.event_from_datetime and evtdt.event_to_datetime) as num_intersects 
    from venues ven left join event_dates evtdt on (ven.id=evtdt.venue_id) 
    group by ven.id
    having num_intersects = 0;

which yields:

+----+----------------+
| id | num_intersects |
+----+----------------+
|  2 |              0 |
+----+----------------+

this also comes up with the right answer (without modification) in the case where you have a venue with no events in the event_date table.


At a guess, if you remove not from

or not ('2009-12-06 00:00:00' between evtdt.event_from_datetime 
                                  and evtdt.event_to_datetime)

this will then return row 1 from event dates but not the other event date rows.

I say "at a guess" because your where clause is a bit hard to understand. Maybe you mean

select ven.id , evtdt.event_from_datetime, evtdt.event_to_datetime 
from venues ven 
left join event_dates evtdt 
on (ven.id=evtdt.venue_id) 
where '2009-12-06 00:00:00' between evtdt.event_from_datetime 
                                  and evtdt.event_to_datetime;
0

精彩评论

暂无评论...
验证码 换一张
取 消