SQL在截止日期之前可用

时间:2018-07-04 07:04:21

标签: sql oracle oracle12c

我有两个桌子。这些看起来像这样

  

桌车

+====+=========+=============+
| ID | mark    | description |
+====+=========+=============+
| 1  | 1234 AB | Volvo V70   |
+----+---------+-------------+
| 2  | 4567 CD | VW GOLF     |
+====+=========+=============+
  

餐桌预订

+====+========+============+============+
| ID | car_id | date_from  | date_to    |
+====+========+============+============+
| 1  | 2      | 2018/01/01 | 2018/02/01 |
+----+--------+------------+------------+
| 2  | 1      | 2018/03/01 | 2018/04/01 |
+----+--------+------------+------------+
| 3  | 1      | 2018/05/01 | 2018/06/01 |
+----+--------+------------+------------+
| 4  | 2      | 2018/07/01 | 2018/08/01 |
+====+========+============+============+

我需要一个SQL查询,该查询返回特定时间段内所有可用的汽车。这意味着:如果我给查询参数2018/01/132018/01/17,我将只得到2号车,因为另一个不可用。

这是我的第一个主意:

select c.id, 
       c.mark
from cars c
join bookings b on c.id = b.car_id
where to_date('2017/01/13', 'yyyy/mm/dd') not between b.date_from and b.date_to
  and to_date('2017/01/17', 'yyyy/mm/dd') not between b.date_from and b.date_to;

这给了我比预期更多的行。

什么是实现此目的的正确查询?

编辑:我正在使用Oracle 12c

3 个答案:

答案 0 :(得分:1)

这可能有效

SELECT DISTINCT c.id,
       c.mark
FROM cars c
JOIN bookings b ON c.id = b.car_id
WHERE (to_date('2017/01/13', 'yyyy/mm/dd') < b.date_from AND to_date('2017/01/17', 'yyyy/mm/dd') < b.date_to)
  OR (to_date('2017/01/13', 'yyyy/mm/dd') < b.date_from AND to_date('2017/01/17', 'yyyy/mm/dd') < b.date_to)

答案 1 :(得分:1)

如果我正确理解了要求,则说明您正在寻找在指定日期范围内未预订的汽车。因此,您不应加入bookings表,因为这只会为您提供在其他期间已预订的汽车。您正在寻找没有预订的汽车,所以:

with cars (id, mark, description) as
       ( select 1, '1234 AB', 'Volvo V70' from dual union all
         select 2, '4567 CD', 'VW Golf' from dual )
   , bookings (id, car_id, date_from, date_to ) as
       ( select 1, 2, date '2018-01-01', date '2018-02-01' from dual union all
         select 2, 1, date '2018-03-01', date '2018-04-01' from dual union all
         select 3, 1, date '2018-05-01', date '2018-06-01' from dual union all
         select 4, 2, date '2018-07-01', date '2018-08-01' from dual )
select c.*
from   cars c
where  not exists
       ( select 1 from bookings b
         where  b.car_id = c.id
         and    (   date '2018-01-13' between b.date_from and b.date_to
                 or date '2018-01-17' between b.date_from and b.date_to )
       );

结果:

        ID MARK    DESCRIPTION
---------- ------- -----------
         1 1234 AB Volvo V70

汽车1可用,因为它只预订3月和5月,而高尔夫只预订1月和7月。

答案 2 :(得分:0)

您尝试过吗:

DECLARE @dateToCheck datetime

SELECT cars.id, cars.mark, cars.description FROM cars
INNER JOIN bookings ON bookings.car_id = car.id
WHERE @dateToCheck BETWEEN booking.date_from AND booking.date_to