在 MySQL 中用连接替换子查询
Posted
技术标签:
【中文标题】在 MySQL 中用连接替换子查询【英文标题】:Replacing Subqueries with Joins in MySQL 【发布时间】:2013-02-12 00:39:49 【问题描述】:我有以下疑问:
SELECT PKID, QuestionText, Type
FROM Questions
WHERE PKID IN (
SELECT FirstQuestion
FROM Batch
WHERE BatchNumber IN (
SELECT BatchNumber
FROM User
WHERE RandomString = '$key'
)
)
我听说子查询效率低下,而联接是首选。但是,我找不到任何解释如何将 3 层以上的子查询转换为连接表示法的内容,也无法理解它。
谁能解释一下怎么做?
【问题讨论】:
如果你发布你的表格结构会很好 【参考方案1】: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'
之所以指定DISTINCT
,是因为可能存在与其他表上的多行匹配的行,导致结果出现重复记录。但由于您只对表 Questions
上的记录感兴趣,因此 DISTINCT
关键字就足够了。
如需进一步了解联接,请访问以下链接:
Visual Representation of SQL Joins【讨论】:
谢谢JW。这是一种享受。我只会说我将a.*
更改为a.PKID, a.QuestionText, a.Type
:)
漫长的一天,我的头完全没有了,但这让我免于绝望【参考方案2】:
试试:
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'
【讨论】:
【参考方案3】: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'
由于您的WHERE
子句过滤了USER
表,因此从FROM
子句中的那个开始。接下来,向后应用您的联接。
【讨论】:
【参考方案4】:为了正确执行此操作,您需要在子查询中使用distinct
。否则,您可能会在连接版本中增加行数:
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
至于in
还是join
版本更好。 . .那要看。在某些情况下,特别是当字段被索引时,in
版本可能没问题。
【讨论】:
以上是关于在 MySQL 中用连接替换子查询的主要内容,如果未能解决你的问题,请参考以下文章