在内部联接中重用 mysql 子查询

Posted

技术标签:

【中文标题】在内部联接中重用 mysql 子查询【英文标题】:Reuse mysql Subquery in InnerJoin 【发布时间】:2013-11-18 11:44:04 【问题描述】:

我正在尝试优化查询,尽量避免重复使用“COMPLEX QUERY”指示的查询,该查询使用了 2 次,并且两次都具有相同的结果。

原始查询

SELECT news.* 
FROM   news 
   INNER JOIN((SELECT myposter 
               FROM   (SELECT **COMPLEX QUERY**)) 
              UNION 
              (SELECT myposter 
               FROM   `profiles_old` prof2 
               WHERE  prof2.profile_id NOT IN (SELECT **COMPLEX QUERY**))) r 
           ON news.profile = r.p 

我想知道这样的事情是否可能:

SELECT news.* 
FROM   (SELECT **COMPLEX QUERY**) complexQuery, 
   news 
   INNER JOIN ((SELECT myposter 
                FROM   complexquery) 
               UNION 
               (SELECT myposter 
                FROM   `profiles_old` prof2 
                WHERE  prof2. profile NOT IN (SELECT myposter 
                                              FROM complexQuery))) r 
           ON news. profile = r.p 

mysql 会对该类型的查询进行某种缓存吗?

【问题讨论】:

嗯,我想看看,但我想我需要实际的子查询来判断什么是最好的解决方案。 另外,如果您提供表结构和查询的 EXPLAIN 结果将会很有用。 问题不是如何实现复杂查询,而是如何重用它的值:在第一部分中,我从复杂查询中获取所有用户,在第二部分中,我尝试获取我之前没有获取的所有用户,来自一个旧表,其中还包含无法从 复杂查询 中检索到的值 【参考方案1】:

您的问题的直接答案是“否”。 MySQL 不支持你想要的。你真正想要的是with 声明。伟大的声明!如果需要,请使用其他数据库。唉。

我确实认为你可以做到这一点,尽管方法与你正在做的完全不同。

逻辑是从复杂查询中获取myposter 的所有值,并从profiles_old 中获取myposter 的所有值,其中对应的profile_id 不在复杂查询中。

您可以使用union all 和聚合来做到这一点。只关注内部子查询:

select (case when max(which = 'cq') = 1 then myposter
             when max(which = 'po') = 1 and max(which = 'cq') = 0 then id2
       ) as myposter
from (select myposter, myposter as id2, 'cq' as which
      from (select **complex query**) cq
      union all
      select profile_id, myposter, 'po' as which
      from profiles_old
     ) t
group by myposter;

剩下的只是将其合并到您的整体查询中。

【讨论】:

【参考方案2】:

我已经完成了要求,以不同的方式给出了建议:

/* 创建临时表(首选使用内存存储引擎,虽然它不是强制性的): */

MYSQL> 创建临时表 tmp_intermediate_table engine=memory select COMPLEX QUERY;

然后,在当前用户会话中运行的查询中引用 tmp_intermediate_table 表。

【讨论】:

这不起作用,因为它需要在同一个查询中重复使用同一个临时表两次,这意味着重新打开同一个表。这在 mysql 中是不允许的 @pankajagarwal,我想你没有明白我的意思,重复使用具有相同复杂查询的临时表可以根据需要多次使用,而无需创建多次。此外,如果您有不同的复杂查询一次并重复使用它们多次,您可以创建单独的临时表。 @pankajagarwal - 请参阅以下参考资料以检​​查 MYSQL 如何允许创建临时表:***.com/questions/5859391/…

以上是关于在内部联接中重用 mysql 子查询的主要内容,如果未能解决你的问题,请参考以下文章

我可以在内部连接条件 sql 中使用子查询吗

数据库(比如MYSQL) ,表连结查询与子查询哪个效率高些? 为啥

mysql 将子查询排除在连接之外

说说 MySQL 子查询

SQl 查询中哪个更好的子查询或联接?

如何将子查询包含到内部联接中?