2011-11-04 2 views
0

저는 자동차 예약 시스템을 구축 중입니다. 구축해야하는 쿼리는 시스템에있는 모든 자동차를 표시하는 쿼리이지만 각 자동차는 2 인으로 예약 할 수 있습니다 동시에.3 테이블 조인 - 외부 조인 중 하나를 사용하여 쿼리를 반환합니다.

나는 완전히 예약되지 않았거나 한 사람이 예약 한 차량 만 표시하고자합니다. 나는 한 사람이 다른 사람과 함께 운전할 사람을 알 수 있도록 사람이 성명을 기입하면 성을 볼 수 있기를 원합니다.

이 내 쿼리는 지금까지하지만, 그 첫 번째 레코드를 반환 여러 번

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' 

Heres는 세 개의 테이블의 구조는

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을 검색합니다.

갱신

내가 주를 선택 쿼리가 내가 그것을 = 'morning_drive'AND 사람이있는 경우는 보여줍니다 그래서 = '2011-11-05'를 일자 슬롯으로 제한 필요한 모든 rows-를 반환하는 것을 알아 낸 그 시간 슬롯의 차를 예약뿐만 아니라 그것은 어떤 사용자가

갱신이

쿼리의 새로운 요구 사항을 실현 기반으로 내가 왼쪽 외부 조인을 추가 한 타임 슬롯에 따른 경고를하지 않았다 차를 반환해야 전체 테이블을 사용하는 대신 하위 쿼리 사용 -

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-하지 무엇을 그 아무것도 반환하지에 가까운

+0

당신이 유일한 기록 검색을위한 DISTINCT 시도 했습니까? – Muse

+0

예, 시도했지만 여러 행을 계속 반환했습니다. –

+0

@ChrisMccabe, 슬롯, 일자 및 유형 기준이 질문에 설명 된 기준과 관련이없는 것으로 보입니다. 이러한 추가 기준이 있습니까? –

답변

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)