检查时间是否在多次之间(时间DataType)

时间:2017-02-18 13:31:05

标签: mysql

我正在使用预订模块进行时间安排。因为我有两个不同的time_data一个时间和另一个booking_time。现在我想展示可用的。

这是带数据的time_data表

|---|---------|
|id |vtime    |
|---|---------|
|1  |08:00:00 |
|2  |09:00:00 |
|3  |10:00:00 |
|4  |11:00:00 |
|5  |12:00:00 |
|6  |13:00:00 |
|7  |14:00:00 |
|8  |15:00:00 |
|9  |16:00:00 |
|10 |17:00:00 |
|11 |18:00:00 |
|12 |19:00:00 |
|13 |20:00:00 |
|14 |21:00:00 |
|15 |22:00:00 |
|---|---------|

这是带数据

的booked_time表
|----|----------|----------------|------------|----------------|-----------|---------|
| id | userid   | facilityid     | courtno    | bookingdate    | starttime | endtime |
|----|----------|----------------|------------|----------------|-----------|---------|
| 1  | 1        |  1             | 1          | 2017-02-20     |08:00:00   |11:00:00 |
| 2  | 3        |  1             | 1          | 2017-02-20     |13:00:00   |15:00:00 |
| 3  | 2        |  1             | 1          | 2017-02-20     |11:00:00   |13:00:00 |
| 4  | 5        |  1             | 1          | 2017-02-21     |11:00:00   |13:00:00 |
|----|----------|----------------|------------|----------------|-----------|---------|

根据booking_time数据运行内部联接查询以获取特定日期的可用时间

我的查询是

SELECT DISTINCT time_data.vtime FROM booked_time INNER JOIN time_data ON  time_data.vtime>=booked_time.endtime OR time_data.vtime<booked_time.starttime WHERE facility_id='1' AND court='1' AND on_date='2017-02-20'

但它显示了所有15条记录的时间。它应该忽略08:00:00,09:00:00,11:00:00,12:00:00,13:00:00,14:00:00,15:00:00。

如何只获得可用时间?使用这些表还是我需要更改数据表结构?

2 个答案:

答案 0 :(得分:1)

我认为你想要的正确逻辑是:

SELECT t.vtime
FROM time_data t LEFT JOIN
     booked_time b      
     ON t.vtime >= b.starttime AND
        t.vtime < b.endtime AND
        b.facility_id = '1' AND b.court = '1' AND
        b.on_date = '2017-02-20'
WHERE b.vtime IS NULL

这会找到所有匹配项并使用LEFT JOIN并与NULL进行比较来删除这些匹配项。

使用NOT EXISTS的替代方案似乎是一种更自然的方法:

select t.vtime
from time_data t
where not exists (select 1
                  from booked_time b      
                  where t.vtime >= b.starttime and
                        t.vtime < b.endtime and
                        b.facility_id = '1' and b.court = '1' and
                        b.on_date = '2017-02-20'
                 );

答案 1 :(得分:0)

SELECT 
  time_data.* 
FROM time_data
LEFT JOIN booked_time ON 
  time_data.vtime BETWEEN booked_time.starttime AND booked_time.endtime
  AND booked_time.facility_id='1' 
  AND booked_time.court='1' 
  AND booked_time.on_date='2017-02-20'
WHERE 
  ISNULL(booked_time.id)

这首先使用LEFT JOIN加入表,以便它包含time_data中没有任何连接记录的记录。 然后它使用WHERE来排除已加入记录的任何行。