возвращение запроса с тремя объединениями таблиц, одно из которых является внешним соединением - PullRequest
0 голосов
/ 04 ноября 2011

Я строю систему бронирования автомобилей, запрос, который мне нужно создать, это тот, который отображает все машины в системе, но каждый автомобиль может быть забронирован 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 голосов
/ 04 ноября 2011

Попробуйте:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...