帮助形成mysql查询以查找给定日期范围的免费(可用)场所/资源

时间:2010-01-12 15:31:12

标签: mysql date join date-range

我有桌子和桌子像这样的数据:

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 | +----+----------+---------------------+---------------------+----------+

这是我的要求:我希望场地在2009-12-06 00:00:00免费 即。

我应该

| venue_id |

| 2 |

目前我有以下查询,

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                |
+----+---------------------+---------------------+

如果您注意到结果,则不包括场地ID 1,其中日期在2009-12-06 00:00:00之间,但显示其他预订。 请帮我纠正这个问题。

提前致谢。

3 个答案:

答案 0 :(得分:2)

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
        )

答案 1 :(得分:1)

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

12/6/2009 在12/5/09和12/7/09之间......这就是为什么scene_id 1被排除在外......你想要提取的是什么从数据到底是什么?

您构建的连接查询说明,获取场地表,并为具有匹配的venue_id的每一行制作场地表行的副本并附加匹配的行。所以,如果你刚刚做了:

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

它会产生:

+----+---------+------+----------+---------------------+---------------------+----------+
| 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 |
+----+---------+------+----------+---------------------+---------------------+----------+

如果您随后添加了条件,该条件表明感兴趣的日期不在事件的发生日期和日期之间,则查询如下:

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)

产生以下结果:

+----+---------+------+----------+---------------------+---------------------+----------+
| 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 |
+----+---------+------+----------+---------------------+---------------------+----------+

这些是我在MySQL中使用您的数据的实际实验结果。

如果你想在建议的日期获得免费的venue_ids,你可以写下这样的内容:

  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;

产生:

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

如果您在event_date表中没有活动的场地,这也会得到正确的答案(无需修改)。

答案 2 :(得分:0)

猜测一下,如果你从

中删除不是
or not ('2009-12-06 00:00:00' between evtdt.event_from_datetime 
                                  and evtdt.event_to_datetime)

这将从事件日期返回第1行,但不返回其他事件日期行。

我说“猜测”因为你的where子句有点难以理解。也许你的意思是

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;