MySQL多表加入

时间:2010-03-15 15:38:15

标签: mysql distinct join

我有3张桌子,我正在尝试加入并获得截然不同的结果。

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中使用distinct,因为我可能有合法的重复项,我想保留。有没有办法使用连接进行此查询而不使用内部选择,如下面的语句?

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

另外,如果我将使用内部选择,是否会出现连接的性能问题?

2 个答案:

答案 0 :(得分: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 BY由于排序而导致MyISAM非常昂贵,因此子查询往往比{{1}}查询更快/物化开销:

答案 1 :(得分:0)

也许你必须在第二个ON

中指定你的意思
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表上的子查询更快。