单选连接 3 个具有 2 个不同 FK 的相关表
我有 3 个表,其中 2 个通过外键与第三个表相关。我想运行这样的查询:
SELECT *
FROM template AS t
LEFT JOIN web_page_content AS wpc ON wpc.template_id = t.id
...并且仍然能够获取标头和模板中的通用 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');
I have 3 tables where 2 of them are related to the third one through a foreign key. I would like to run a query like:
SELECT *
FROM template AS t
LEFT JOIN web_page_content AS wpc ON wpc.template_id = t.id
...and still be able to get the common id's in header and template.
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');
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是您要找的吗?
-- 编辑 --
澄清子选择与每个评论/反馈的加入。
在这种情况下,您可以通过模板 ID 以 1:1 的比例从一个表直接连接到另一个表。引擎直接在索引上找到匹配项,然后提取数据。它几乎就像引擎隐式地为您在密钥 ID 上执行 (select / from / where ) 一样。我不明白它是如何做到的,但它只是做得很好。通过执行子选择,您将强制引擎针对每个 ID 的模板表中的每条记录显式运行查询...假设您有 20 个模板和 1000 个网页内容页面。通过执行子选择(例如 where EXISTS),实际上每个匹配的 ID 都会显式运行 select/from 查询 1000 次。
对于笛卡尔,如果您只列出没有连接条件的“From”表,您将得到一个结果集,其数量与表“A”中的记录数乘以表“B”中的记录数。因此,如果您执行了简单,
没有 WHERE(连接它们)或显式 JOIN,并且上面的记录计数示例...您最终会在结果集中得到 20,000 条记录。
Is this what you are looking for?
-- EDIT --
To clarify sub-selects vs join per comment/feedback.
In this case, you have the capacity to do a direct join from one table to another in a 1:1 ratio by the template ID. The engine finds matches directly on the indexes to then pull the data. Its almost like the engine is implicitly doing a (select / from / where ) on the key ID for you. I don't understand the whole under-the-hood of HOW it does it, it just does it well. By doing a sub-select, you are forcing the engine to explicitly run the query for every record in template table per ID... Say you have 20 templates, and 1000 web content pages. By doing a sub-select (such as where EXISTS) would in effect run the select/from query 1000 times explicitly per ID matched.
With respect to a Cartesian, if you just listed the "From" tables without a join condition, you get a result set that is as many records form table "A" TIMES as many in table "B".. so if you did a simple
WITHOUT a WHERE (joining them), or explicit JOIN, and the above record counts sample... you would end up with 20,000 records in the result set.