【发布时间】:2011-12-21 21:11:02
【问题描述】:
我正在构建一个汽车预订系统,我需要构建的查询是显示系统中所有汽车的查询 - 但每辆车可以同时被 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-它将检索那个人的名字和姓氏
更新
我发现主选择查询正在返回所有行-我需要将其限制为 slot = 'morning_drive' AND dated = '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 - 它什么也不返回
【问题讨论】:
-
您是否尝试过 DISTINCT 进行唯一记录检索?
-
是的,我试过了,但它仍然返回多行
-
@ChrisMccabe,您选择的位置、日期和类型标准似乎与问题中描述的标准无关。这些是额外的标准吗?
-
您现有的设置将只允许一个人多次预订同一辆车 - 例如,汽车 X1 只能由 John Smith 预订一天,而 Fred Brown 只能在另一天预订.然后,您的查询将返回 car X1 两次,一次为 John Smith,一次为 Fred Brown。
-
我发现主选择查询正在返回所有行 - 我需要将其限制为 slot = 'morning_drive' AND dated = '2011-11-05' 所以它显示一个人是否有预订了该时间段的汽车,但还需要退回没有用户为该时间段预订的汽车