我有两个桌子。这些看起来像这样
桌车
+====+=========+=============+
| 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/13
和2018/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
答案 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