MySQL Multi Table Table Join - PullRequest
       26

MySQL Multi Table Table Join

4 голосов
/ 15 марта 2010

У меня есть 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 | 
+-------+-----------------------------------------------+-----------------------------------------------+

Я получаю дубликаты, и это то, что я хотел бы получить.

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

Я не могу использовать Different в 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

Кроме того, если я буду использовать внутренние выборки, будут ли проблемы с производительностью по сравнению с объединениями?

Ответы [ 2 ]

0 голосов
/ 15 марта 2010

Может быть, вы должны указать, какой car_id вы имеете в виду во втором 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.

0 голосов
/ 15 марта 2010

Есть ли способ выполнить этот запрос, используя объединения и не используя внутренние выборки, как в приведенном ниже утверждении?

Существует, но не так эффективно и может опускать некоторые предполагаемые дубликаты:

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 довольно дорого из-за накладных расходов на сортировку / материализацию:

...