2015-01-16 49 views
0

我有两个表名carsbooking。 我想找到的是可用的预订车,简单的是从cars中选择车辆的详细信息,其ID在特定日期和时间不在预订表中。MySQL选择不在特定日期和时间的ID

预订表的列有pick_date(date),drop_date(date),pick_time(time),drop_time(time),car_id(int),booking_id(int) blah blah

现在我被困在获得可用的汽车。请你指导我如何在MySQL中做到这一点。以下是预订表的4列。

Pick_Date Drop_Date Pick_Time  Drop_Time 
---------- ----------- -----------  -------------- 
2015-01-15 2015-01-15 09:00:00.000000 10:00:00.000000 
+0

没有先生这是完全不同的东西 –

+0

什么是问题和你使用什么查询?日期和时间没有任何格式,它们是二进制值。 –

+0

是的,RiggsFolly提到的问题完全是一回事。 – RandomSeed

回答

0

试试这个:

SELECT c.car_id 
FROM cars c 
LEFT JOIN (SELECT car_id 
      FROM bookings 
      WHERE '2015-01-15 11:00:00' BETWEEN CAST(CONCAT(Pick_Date, ' ', Pick_Time) AS DATETIME) AND CAST(CONCAT(Drop_Date, ' ', Drop_Time) AS DATETIME) 
     ) AS A ON c.car_id = A.car_id 
WHERE A.car_id IS NULL 
+0

将函数应用于像这样的字段可防止数据库使用索引并导致全表扫描。 –

+0

谢谢我被困在很长的时间里,你已经给出了非常快速和很好的答案。谢谢 –

+0

你会explian @PanagiotisKanavos? –

0

您可以使用“NOT IN” MySql.Read的此,如果仍然需要帮助,请发表评论。

SELECT * FROM cars WHERE cars.id NOT IN (SELECT id FROM booking); 

希望这个查询会帮助你。

1

你可以用left joinnot innot exists来做到这一点。该left join看起来像

select c.* 
from cars c left join 
    bookings b 
    on c.car_id = b.car_id and 
     @pickdt <= addtime(drop_date, drop_time) and 
     @dropdt >= addtime(pick_date, pick_time) 
where b.car_id is null; 

变量@pickdt@dropdt是你正在寻找的拿起和落倍。这将检查该期间和预订期间之间是否有重叠。它选择根本没有重叠的汽车。

注意:您应该将日期时间值存储在单个列中,而不是两个单独的值与日期和时间。

+0

将函数应用于这样的字段可防止数据库使用索引并导致全表扫描。单列将消除该问题。事实上,WHERE'语句应该在一个比较日期的部分和一个比较时间的部分中分解,只有日期相同。非常丑陋,但确保生产性能的唯一途径 –

+0

@PanagiotisKanavos。 。 。这可能不会导致“全表扫描”,而是在索引扫描中,因为“car_id”上的相等条件。尽管如此,将日期/时间值存储在单个字段中将允许使用组合索引,这会加快查询速度。 –

+0

'car_id'上的唯一条件是对连接结果进行空检查,因此它不具有选择性。它确实取决于底层的数据统计信息以及查询优化器如何决定执行查询。在这两种情况下,性能都会非常糟糕 –

相关问题