我需要基于保存在同一表上的现有“预订”从表1中检索可用的“汽车”,其中“汽车”和“预订”具有相同的元表,用于保存预订的开始日期和元数据表中key => value列中的结束时间,例如:
carA有以下保留:
如果用户查询7月15日至7月17日的可用汽车,则应返回carA。
如果查询7月14日至7月17日可用的汽车,则carA不可用。
如果查询7月16日至7月18日可用的汽车,则carA不可用。
如果查询7月16日至7月21日可用的汽车,则carA不可用。
进一步详细说明,这是简化的数据库架构:
表1-项目
表2-items-meta
+------+-----------------+--------------+
| id | type | item |
+------+-----------------+--------------+
| 1 | car | carA |
| 2 | car | carB |
| 3 | car | carC |
| 18 | car | carD |
| 4 | reservation | reservationA |
| 5 | reservation | reservationB |
| 6 | reservation | reservationC |
| 7 | reservation | reservationD |
| 8 | reservation | reservationE |
| 9 | reservation | reservationF |
| 10 | reservation | reservationH |
| 11 | reservation | reservationI |
+------+-----------------+--------------+
+-----+---------+--------------+---------------------+
| id | rid | key | value |
+-----+---------+--------------+---------------------+
| 1 | 4 | start_time | 2018-07-4 11:51:34 |
| 2 | 4 | end_time | 2018-07-8 11:51:34 |
| 3 | 4 | car_id | 1 |
| 4 | 5 | start_time | 2018-07-9 11:51:34 |
| 5 | 5 | end_time | 2018-07-14 11:51:34 |
| 6 | 5 | car_id | 1 |
| 7 | 6 | start_time | 2018-07-18 11:51:3 |
| 8 | 6 | end_time | 2018-07-20 11:51:34 |
| 9 | 6 | car_id | 1 |
| 10 | 7 | start_time | 2018-07-18 11:51:3 |
| 11 | 7 | end_time | 2018-07-20 11:51:34 |
| 12 | 7 | car_id | 18 |
+-----+---------+--------------+---------------------+
我认为这是一个有趣的挑战,不知道该如何将查询结构化以达到该目的,甚至可能?感谢您的帮助,谢谢。
答案 0 :(得分:0)
我创建了一个子查询,该查询将项元数据转换为具有汽车ID,预订ID,开始时间和结束时间的单个表。这在下面的查询中以表R表示。一旦数据采用这种格式,您就可以查询预订数据以查看搜索日期和现有预订之间有什么重叠。
以下查询提供了与给定搜索日期冲突的所有保留的列表。您可以使用此列表来知道要排除哪些汽车,因为在搜索日期它们已经被保留。
set @SearchStartTime = cast('2018-07-03 00:00:00' as datetime);
set @SearchEndTime = cast('2018-07-05 00:00:00' as datetime);
select carID, rid, StartTime, EndTime from
(
select Cars.`value` as carID, coalesce(Starts.rid, Ends.rid) as rid, StartTime, EndTime from
(select id, rid, `value` from items_meta
where `key`='car_id' ) Cars
left outer join
(select id, rid, cast(`value` as datetime) as StartTime from items_meta
where `key`='start_time' ) Starts
on Starts.rid = Cars.rid
left outer join
(
select id, rid, cast(`value` as datetime)as EndTime from items_meta
where `key`='end_time') Ends
on Ends.rid = Cars.rid
) R
where
(
@SearchStartTime between R.StartTime and R.EndTime
or
@SearchEndTime between R.StartTime and R.EndTime
or
R.StartTime between @SearchStartTime and @SearchEndTime
or
R.EndTime between @SearchStartTime and @SearchEndTime
)