开发者

MySQL Multiple Table Join

开发者 https://www.devze.com 2022-12-23 03:30 出处:网络
I have a 3 tables that I\'m trying to join and get distinct results. CREATE TABLE`car` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT,

I have a 3 tables that I'm trying to join and get distinct results.

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 | 
+----+-------------+--------+

Here is my query.

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 | 
+开发者_高级运维-------+-----------------------------------------------+-----------------------------------------------+

I get duplicate entires and this is what I would like to get.

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

I cannot use distinct in group_concat because I might have legitimate duplicates which I would like to keep. Is there any way to do this query using joins and not using inner selects like the statement below?

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

Also, if I will use inner selects, will there be any performance issues over joins?


Is there any way to do this query using joins and not using inner selects like the statement below?

There is, but not as efficient and can omit some intended duplicates:

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;

Also, if I will use inner selects, will there be any performance issues over joins?

In your very case, yes: the subselects will be faster.

On MyISAM tables, in some cases the subselects tend to be faster than GROUP BY queries, due to the fact that GROUP BY in MyISAM is quite expensive due to sorting / materialization overhead:

  • Aggregates: subqueries vs. GROUP BY


Maybe you have to specify which car_id you mean in the second 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;

I believe joins are faster than subqueries on InnoDB tables.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号