我有 2 张 table :
CREATE TABLE `categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`asset_id` int(10) unsigned NOT NULL DEFAULT '0',
`title` mediumtext NOT NULL,
`published` tinyint
)
CREATE TABLE `content` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`asset_id` int(10) unsigned NOT NULL DEFAULT '0',
`title` mediumtext NOT NULL,
`catid` int(10) unsigned NOT NULL DEFAULT '0'
)
内容表中的“catid”也存储该内容所属的类别(即类别表中的“id”) 现在,我想提取“有效” Assets 的列表(类别和内容)。我使用以下查询,其中列出了所有“已发布”类别及其中的内容。
SELECT asset_id, title
FROM (SELECT asset_id, title FROM categories WHERE published=1) AS ca
UNION ALL
(SELECT asset_id, title FROM content WHERE catid IN
(select id FROM categories WHERE published = 1)
)
我可以得到想要的结果。但是,您可以看到在查询中,FROMcategories WHEREpublished=1
已被重复(在实际情况中,条件比仅仅 published=1
长得多) 。有更好的方法吗?
由于我的 Assets 包括“类别”内“内容”内的“图像”,因此我需要在 UNION ALL
的每个子查询中重复整个条件。调试查询就像 hell 一样。
我在想是否有办法从类别中选择 id、asset_id、title ... AS ca
,然后提取“id”列作为第二个子查询的集合FROM content WHERE id IN ca.id
(当然这是行不通的)。我尝试了“WITH”,但Mysql不支持它。非常感谢。
最佳答案
JOIN
解决方案可能是最佳方式...
...但是如果您想保留子查询语法(例如,为了可读性),为什么不重新组织它呢?
如果我理解得很好,您需要所有具有“published=1”的类别以及属于此类类别的所有内容(根据asset_id
)。因此,以下查询应该产生几乎相同的结果(多一列):
SELECT asset_id, title
FROM (SELECT asset_id, title, id FROM categories
UNION ALL
SELECT asset_id, title, catid FROM content
) AS s
WHERE s.id IN (select id FROM categories WHERE published = 1)
注意我直接在SO上输入。请原谅拼写错误和其他语法错误...
从性能的角度来看,这可能不是很好,因为我打赌它将需要临时表+文件排序。但我不确定联接在这方面会表现更好,因为您需要两个表的 UNION
...
如果由于某种原因,检查表categories
两次的成本太并且如果预期结果相对较小,也许您可以使用临时表/ View 来保存查询的中间结果(您甚至可能希望使用ENGINE MEMORY
)。
很难判断这是否比原始查询更有效。这将取决于许多因素。无论如何,这次使用 JOIN
:
CREATE TEMPORARY TABLE cache ENGINE MEMORY
AS SELECT categories.asset_id as cat_aid, categories.title AS cat_t, categories.id AS cat_i,
content.asset_id as con_aid, content.title AS con_t, content.catid AS con_i
FROM categories
LEFT JOIN content
ON content.catid = categories.id
WHERE categories.published = 1;
获得所需的结果只需在该表上执行SELECT ... UNION ...
即可:
SELECT DISTINCT cat_aid, cat_t FROM cache
UNION ALL SELECT DISTINCT con_aid, con_t FROM cache;
关于mysql - 重用提取子查询的列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18226735/