mysql - 重用提取子查询的列?

标签 mysql subquery

我有 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;

参见http://sqlfiddle.com/#!2/32ee4/2

关于mysql - 重用提取子查询的列?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18226735/

相关文章:

mysql - Select Projections.constructor 中的子查询

mysql - 子查询 : slow. 中的 GROUP BY 使用 View 有帮助,但这可以在一个查询中完成吗?

php - mysqli 绑定(bind)变量

php - Mysql查询WHERE列在json数组中

sql - JOIN 打破 WHERE 子查询

mysql - 使用mysql子查询更新错误: Subquery returns more than 1 row

c# - 单击按钮时从数据库获取随机 ID

php - 从 php 回显 html 代码到 html

php - 如何获取mysql中每组的最低值

mysql - 使用 "IN"关键字的子查询