简体   繁体   English

用MySQL中的连接替换子查询

[英]Replacing Subqueries with Joins in MySQL

I have the following query: 我有以下查询:

SELECT PKID, QuestionText, Type 
FROM Questions 
WHERE PKID IN (
    SELECT FirstQuestion 
    FROM Batch 
    WHERE BatchNumber IN (
        SELECT BatchNumber 
        FROM User 
        WHERE RandomString = '$key'
    )
)

I've heard that sub-queries are inefficient and that joins are preferred. 我听说子查询效率低,而且连接是首选。 I can't find anything explaining how to convert a 3+ tier sub-query to join notation, however, and can't get my head around it. 但是,我无法找到解释如何将3+层子查询转换为连接符号的任何内容,并且无法理解它。

Can anyone explain how to do it? 任何人都可以解释如何做到这一点?

SELECT  DISTINCT a.*
FROM    Questions a
        INNER JOIN Batch b
            ON a.PKID = b.FirstQuestion
        INNER JOIN User c
            ON b.BatchNumber = c.BatchNumber
WHERE   c.RandomString = '$key'

The reason why DISTINCT was specified is because there might be rows that matches to multiple rows on the other tables causing duplicate record on the result. 指定DISTINCT的原因是因为可能存在与其他表上的多行匹配的行,从而导致结果上出现重复记录。 But since you are only interested on records on table Questions , a DISTINCT keyword will suffice. 但由于您只对表格Questions记录感兴趣,因此DISTINCT关键字就足够了。

To further gain more knowledge about joins, kindly visit the link below: 要进一步了解联接,请访问以下链接:

Try : 试试:

SELECT q.PKID, q.QuestionText, q.Type 
FROM Questions q
INNER JOIN Batch b ON q.PKID = b.FirstQuestion
INNER JOIN User u ON u.BatchNumber = q.BatchNumber
WHERE u.RandomString = '$key'
select
    q.pkid,
    q.questiontext,
    q.type
from user u
join batch b
    on u.batchnumber = b.batchnumber
join questions q
    on b.firstquestion = q.pkid
where u.randomstring = '$key'

Since your WHERE clause filters on the USER table, start with that in the FROM clause. 由于您的WHERE子句在USER表上进行过滤,因此请FROM子句中开始。 Next, apply your joins backwards. 接下来,向后应用您的连接。

In order to do this correctly, you need distinct in the subquery. 为了正确执行此操作,您需要在子查询中使用distinct Otherwise, you might multiply rows in the join version: 否则,您可能会在连接版本中乘以行:

SELECT q.PKID, q.QuestionText, q.Type 
FROM Questions q join
     (select distinct FirstQuestion
      from Batch b join user u
           on b.batchnumber = u.batchnumber and
              u.RandomString = '$key'
     ) fq
     on q.pkid = fq.FirstQuestion

As to whether the in or join version is better . 至于injoin版本是否更好。 . . that depends. 那要看。 In some cases, particularly if the fields are indexed, the in version might be fine. 在某些情况下,特别是如果字段被索引, in版本可能没问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM