返回具有3个表连接的查询 - 一个是外连接

时间:2011-11-04 09:47:27

标签: mysql sql

我正在建立一个汽车预订系统,我需要建立的查询显示系统中的所有汽车 - 但每辆汽车可以同时由2个人预订。

我只想展示尚未完全预订或仅由一个人预订过的车辆。我希望能够看到这个人的名字和姓氏,如果它已被一个人预订,那么其他人可以告诉他们将与谁一起开车。

这是我的查询到目前为止,但它多次返回第一条记录

 SELECT cars.*, people.first_name, people.last_name 
FROM 
    cars 
LEFT JOIN booking on cars.id = booking.car LEFT OUTER JOIN people ON booking.person_1 = people.id
WHERE cars.id NOT IN 
(SELECT car
 FROM booking WHERE slot = 'morning_drive' AND dated = '2011-11-05' AND person_1 != '' AND person_2 != '') AND cars.type = '911' 

这是三个表的结构

CREATE TABLE `cars` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL,
  `description` text NOT NULL,
  `large_img_url` varchar(250) NOT NULL,
  `small_img_url` varchar(250) NOT NULL,
  `nr` varchar(100) NOT NULL,
  `license_plate` varchar(100) NOT NULL,
  `exterior_color` varchar(100) NOT NULL,
  `interior_color` varchar(100) NOT NULL,
  `PDK` tinyint(1) NOT NULL,
  `Manual` tinyint(1) NOT NULL,
  `type` enum('911','vintage') NOT NULL,
  `power` varchar(100) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=27 ;



CREATE TABLE `booking` (
  `id` int(11) NOT NULL auto_increment,
  `slot` enum('morning_drive','afternoon_loop','return_drive') NOT NULL,
  `type` enum('911','vintage_911') NOT NULL,
  `car` int(11) NOT NULL,
  `person_1` int(11) default NULL,
  `person_2` int(11) default NULL,
  `dated` date NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=25 ;


CREATE TABLE `people` (
  `id` int(11) NOT NULL auto_increment,
  `first_name` varchar(50) NOT NULL,
  `last_name` varchar(50) NOT NULL,
  `organisation` varchar(100) NOT NULL,
  `event_date` date NOT NULL,
  `wave` varchar(20) NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=454 ;

那么如何让我的查询基本上只返回每辆车一行,只显示没有(person_2)和没有(person_1或person_2)的汽车,如果汽车确实有person_1-它将检索那些人first_name和last_name

更新

我已经发现主选择查询正在返回所有行 - 我需要将它限制为slot ='morning_drive'和日期='2011-11-05'所以它显示一个人是否为此预订了汽车时间段,但它也需要返回没有用户为该时间段预订的汽车

更新2

基于实现查询的新要求,我添加了一个左外连接子查询,而不是使用完整的表 -

 SELECT cars.*, people.first_name, people.last_name 
FROM 
    cars 
LEFT OUTER JOIN (SELECT car, person_1 FROM booking WHERE  slot = 'morning_drive' AND dated = '2011-11-05' AND booking.person_1 != '' AND booking.person_2 = '') bookings on cars.id = bookings.car LEFT  JOIN people ON bookings.person_1 = people.id
WHERE cars.id NOT IN 
    (SELECT car
 FROM booking WHERE slot = 'morning_drive' AND dated = '2011-11-05' AND person_1 != '' AND person_2 != '')
 AND cars.type = '911'

这更接近我想要的东西,但它不加入人员表first_names和last_names-它什么都不返回

1 个答案:

答案 0 :(得分:0)

尝试:

SELECT cars.*, people.first_name, people.last_name 
FROM cars 
JOIN booking on cars.id = booking.car
JOIN people on booking.person_1 = people.id
WHERE  booking.slot = 'morning_drive'     AND 
       booking.dated = '2011-11-05'       AND 
       coalesce(booking.person_2,'') = '' AND 
       cars.type = '911'
UNION
SELECT cars.*, '' first_name, '' last_name 
FROM cars
WHERE  cars.type = '911' AND 
       NOT EXISTS
       (SELECT NULL FROM booking 
        WHERE slot = 'morning_drive' AND 
              dated = '2011-11-05'   AND 
              cars.id = bookings.car)