根据另一个元表和用户输入上的条件从表中选择

时间:2018-07-31 19:00:38

标签: mysql sql relational-database schema mariadb

我需要基于保存在同一表上的现有“预订”从表1中检索可用的“汽车”,其中“汽车”和“预订”具有相同的元表,用于保存预订的开始日期和元数据表中key => value列中的结束时间,例如:

carA有以下保留:

  1. 7月4日至7月8日
  2. 7月9日至7月14日
  3. 7月18日至7月20日

如果用户查询7月15日至7月17日的可用汽车,则应返回carA。
如果查询7月14日至7月17日可用的汽车,则carA不可用。
如果查询7月16日至7月18日可用的汽车,则carA不可用。
如果查询7月16日至7月21日可用的汽车,则carA不可用。

进一步详细说明,这是简化的数据库架构:

表1-项目
表2-items-meta

塔贝尔1(物品)

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

塔贝尔2(项-元)

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

我认为这是一个有趣的挑战,不知道该如何将查询结构化以达到该目的,甚至可能?感谢您的帮助,谢谢。

1 个答案:

答案 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
)