如何消除从表到另一个表的结果?

时间:2012-04-29 18:36:42

标签: php mysql

我知道头衔真的很荒谬。我找不到如何形容这一点。

这是我的表结构 enter image description here

这是一个租车网页。我正在做的是我试图找出一辆汽车是否特别保留了“pickup_date”和“dropoff_date”。 我可以通过此查询获得预订车辆

SELECT
cars.model,
reservations.pickup_date,
reservations.dropoff_date,
reservations.car_id
FROM
cars
INNER JOIN reservations ON cars.car_id = reservations.car_id
WHERE
reservations.pickup_date <= '2012-04-08 10:50:26' OR
reservations.dropoff_date >= '2012-04-20 10:50:26'

但是,有些汽车没有预留,并且未在此查询中显示,因为我没有预订所有车型。我把它们放在汽车桌上。

最重要的是,我应该从包含所有车型的表格中删除我从此查询中获得的那些。因此,我将拥有未预订的车辆+预订日期后可用的车辆。

它将获得我从查询中获得的结果,并从 cars 表中消除此结果。之后会告诉我。

我可以用PHP做到这一点。但是,我想学习是否可以使用mysql进行一次查询。

这是我在@cbuckley

的帮助下提出的解决方案
SELECT
cars.*
FROM cars
LEFT JOIN (
    SELECT
    cars.car_id
    FROM
    cars
    INNER JOIN reservations
    ON cars.car_id = reservations.car_id
    WHERE
    (reservations.pickup_date <= '2012-04-08 10:50:26' AND reservations.dropoff_date >= '2012-04-20 10:50:26') OR
    (reservations.pickup_date >= '2012-04-08 10:50:26' AND reservations.pickup_date <= '2012-04-20 10:50:26') OR
    (reservations.dropoff_date <= '2012-04-20 10:50:26' AND reservations.dropoff_date >= '2012-04-08 10:50:26')
) AS reserved_cars
ON reserved_cars.car_id = cars.car_id
WHERE reserved_cars.car_id IS NULL;

2 个答案:

答案 0 :(得分:1)

使用左连接而不是内连接

SELECT
cars.model,
reservations.pickup_date,
reservations.dropoff_date,
reservations.car_id
FROM
cars
LEFT JOIN reservations ON cars.car_id = reservations.car_id
WHERE
reservations.pickup_date <= '2012-04-08 10:50:26' OR
reservations.dropoff_date >= '2012-04-20 10:50:26'

它会给你所有尚未保留的车辆

答案 1 :(得分:0)

您需要小心区分汽车在给定时间没有预订汽车在预定时间以外的时间预订。前者是你所追求的,可以通过WHERE NOT IN子句来实现。然而,随着您的汽车和预订系统的增长,这可能变得非常缓慢。我建议如下:

SELECT
cars.*
FROM cars
LEFT JOIN (
    SELECT
    cars.car_id
    FROM
    cars
    INNER JOIN reservations
    ON cars.car_id = reservations.car_id
    WHERE
    reservations.pickup_date <= '2012-04-08 10:50:26' OR
    reservations.dropoff_date >= '2012-04-20 10:50:26'
) AS reserved_cars
ON reserved_cars.car_id = cars.car_id
WHERE reserved_cars.car_id IS NULL;

内部查询是您指定查找所有预留车辆的查询。然后,您将其加入cars表,以查找内部查询未返回的所有汽车。这是有效的,因为您对子查询执行LEFT JOIN并且只返回子查询中没有匹配的行。

编辑:如果您希望查询查找给定时间段内可用的所有汽车,则您的内部查询需要搜索在该时段内开始或结束的预订。因此,您将使用以下条件:

... WHERE
reservations.pickup_date  BETWEEN '2012-04-08 10:50:26' AND '2012-04-20 10:50:26' OR
reservations.dropoff_date BETWEEN '2012-04-08 10:50:26' AND '2012-04-20 10:50:26'