2010-03-15 69 views
4

我有一个3表,我试图加入并获得不同的结果。MySQL多表加入

CREATE TABLE `car` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL DEFAULT '', 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB 

mysql> select * from car; 

+----+-------+ 
| id | name | 
+----+-------+ 
| 1 | acura | 
+----+-------+ 




CREATE TABLE `tires` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `tire_desc` varchar(255) DEFAULT NULL, 
    `car_id` int(10) unsigned NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `new_fk_constraint` (`car_id`), 
    CONSTRAINT `new_fk_constraint` FOREIGN KEY (`car_id`) REFERENCES `car` (`id`) ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE=InnoDB 

mysql> select * from tires; 

+----+-------------+--------+ 
| id | tire_desc | car_id | 
+----+-------------+--------+ 
| 1 | front_right |  1 | 
| 2 | front_left |  1 | 
+----+-------------+--------+ 


CREATE TABLE `lights` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT, 
    `lights_desc` varchar(255) NOT NULL, 
    `car_id` int(10) unsigned NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `new1_fk_constraint` (`car_id`), 
    CONSTRAINT `new1_fk_constraint` FOREIGN KEY (`car_id`) REFERENCES `car` (`id`) ON DELETE CASCADE ON UPDATE CASCADE 
) ENGINE=InnoDB 

mysql> select * from lights; 

+----+-------------+--------+ 
| id | lights_desc | car_id | 
+----+-------------+--------+ 
| 1 | right_light |  1 | 
| 2 | left_light |  1 | 
+----+-------------+--------+ 

这是我的查询。

mysql> SELECT name, group_concat(tire_desc), group_concat(lights_desc) 
FROM car 
left join tires on car.id = tires.car_id 
left join lights on car.id = car_id 
group by car.id; 

+-------+-----------------------------------------------+-----------------------------------------------+ 
| name | group_concat(tire_desc)      | group_concat(lights_desc)      | 
+-------+-----------------------------------------------+-----------------------------------------------+ 
| acura | front_right,front_right,front_left,front_left | right_light,left_light,right_light,left_light | 
+-------+-----------------------------------------------+-----------------------------------------------+ 

我得到重复的entires,这就是我想得到的。

+-------+-----------------------------------------------+--------------------------------+ 
| name | group_concat(tire_desc) | group_concat(lights_desc) | 
+-------+-----------------------------------------------+--------------------------------+ 
| acura | front_right,front_left | right_light,left_light | 
+-------+-----------------------------------------------+--------------------------------+ 

我不能在group_concat中使用不同的,因为我可能有合法的重复,我想保留。有没有办法使用连接来做这个查询,而不是像下面的语句那样使用内部选择?

SELECT name, 
(select group_concat(tire_desc) from tires where car.id = tires.car_id), 
(select group_concat(lights_desc) from lights where car.id = lights.car_id) 
FROM car 

此外,如果我将使用内部选择,将有任何性能问题超过联接?

回答

0

是否有任何方法可以使用连接执行此查询,而不是像以下语句那样使用内部选择?

有,但效率不高,可以省略一些打算重复:

SELECT name, group_concat(DISTINCT tire_desc), group_concat(DISTINCT lights_desc) 
FROM car 
left join tires on car.id = tires.car_id 
left join lights on car.id = car_id 
group by car.id; 

另外,如果我会用内选择,将有超过加入任何性能问题?

在你的情况下,是的:子选择会更快。

MyISAM表,在某些情况下,子查询往往快于GROUP BY疑问,由于事实GROUP BYMyISAM是相当昂贵的,因为排序/物化开销:

0

也许你必须指定在第二个ON中你指的是哪个car_id

SELECT name, group_concat(tire_desc), group_concat(lights_desc) 
FROM car 
left join tires on car.id = tires.car_id 
left join lights on car.id = **lights**.car_id 
group by car.id; 

我相信连接速度快于InnoDB表上的子查询。