Единый выбор, чтобы объединить 3 связанных таблицы с 2 различными FK - PullRequest
0 голосов
/ 25 октября 2011

У меня есть 3 таблицы, 2 из которых связаны с третьей через внешний ключ.Я хотел бы выполнить запрос вроде:

SELECT * 
FROM template AS t 
LEFT JOIN web_page_content AS wpc ON wpc.template_id = t.id

... и при этом иметь возможность получать общие идентификаторы в заголовке и шаблоне.

CREATE TABLE template 
(
  id INT AUTO_INCREMENT NOT NULL, 
  uri VARCHAR(50) NOT NULL,    
  UNIQUE INDEX template_idx (uri), PRIMARY KEY(id)
) ENGINE = InnoDB;

CREATE TABLE web_page_content 
(
  id INT AUTO_INCREMENT NOT NULL, 
  template_id INT NOT NULL, 
  content VARCHAR(50) NOT NULL, 
  PRIMARY KEY(id)
) ENGINE = InnoDB;

CREATE TABLE header 
(
  id INT AUTO_INCREMENT NOT NULL, 
  template_id INT NOT NULL, 
  content VARCHAR(50) NOT NULL, 
  PRIMARY KEY(id)
) ENGINE = InnoDB;

ALTER TABLE web_page_content 
ADD CONSTRAINT FK_95E4B6E5627579FF FOREIGN KEY (template_id) 
    REFERENCES template(id) ON DELETE CASCADE;

ALTER TABLE header 
ADD CONSTRAINT FK_95E3B5E5627579FF FOREIGN KEY (template_id) 
    REFERENCES template(id) ON DELETE CASCADE;  

INSERT INTO `template` (`id`, `uri`) VALUES (NULL, 'my_dir/my_file_0'), (NULL, 'my_dir/my_file_1');

1 Ответ

0 голосов
/ 25 октября 2011

Это то, что вы ищете?

select 
      t.ID,
      t.uri,
      h.ID as HeaderID,
      h.Content as HeaderContent,
      wpc.id as WebPageID,
      wpc.Content as WebContent
   from
      template t
         left join header h
            on t.id = h.template_id
         left join web_page_content wpc
            on t.id = wpc.template_id

- РЕДАКТИРОВАТЬ -

Для уточнения подвыборов против присоединения за комментарий / отзыв.

В этом случае у вас есть возможность выполнить прямое соединение из одной таблицы в другую в соотношении 1: 1 по идентификатору шаблона.Движок находит совпадения непосредственно по индексам, чтобы затем извлекать данные.Это почти как движок, который неявно выполняет (выбрать / откуда / где) идентификатор ключа для вас.Я не понимаю всей сути того, КАК это делает, просто делает это хорошо.Делая суб-выбор, вы заставляете механизм явно выполнять запрос для каждой записи в таблице шаблонов для каждого идентификатора ... Допустим, у вас есть 20 шаблонов и 1000 страниц веб-контента.Выполнение суб-выбора (например, где EXISTS) фактически запустит запрос select / from 1000 раз явно для соответствующего идентификатора.

Что касается декартовой системы, если вы только что перечислили таблицы «От» безпри условии соединения вы получите набор результатов, который будет составлять столько же записей из таблицы «A» РАЗ, сколько в таблице «B» .. так что если вы сделали простое

select
     t.*,
     wpc.*
   from
      template t,
      web_page_content wpc
   order by...

БЕЗ ГДЕ (соединяя их), или явное JOIN, и приведенная выше запись насчитывает выборку ... в результате вы получите 20 000 записей в наборе результатов.

...