首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从属SubQuery v左联接

从属SubQuery v左联接
EN

Stack Overflow用户
提问于 2012-07-21 12:12:19
回答 2查看 174关注 0票数 0

这个查询显示了正确的结果,但在执行解释时,它将其列为"Dependant SubQuery“,我认为这是错误的?

代码语言:javascript
复制
SELECT Competition.CompetitionID, Competition.CompetitionName,     Competition.CompetitionStartDate  
FROM Competition  
WHERE CompetitionID NOT   
IN (  
SELECT CompetitionID  
FROM PicksPoints  
WHERE UserID =1    
)

我尝试将查询更改为:

代码语言:javascript
复制
SELECT Competition.CompetitionID, Competition.CompetitionName,   Competition.CompetitionStartDate  
FROM Competition  
LEFT JOIN PicksPoints ON Competition.CompetitionID = PicksPoints.CompetitionID  
WHERE UserID =1  
and PicksPoints.PicksPointsID is null  

但它显示0行。与第一个实际工作的查询相比,上面的查询有什么问题?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-07-21 12:48:55

秒查询不能生成行:它声明:

代码语言:javascript
复制
WHERE UserID =1  
and PicksPoints.PicksPointsID is null 

但为了澄清,我重写如下:

代码语言:javascript
复制
WHERE PicksPoints.UserID =1  
and PicksPoints.PicksPointsID is null 

因此,一方面,您在PicksPoints where UserId = 1上请求行,但是再次,您希望该行从一开始就不存在。你能看到失败吗?

外部连接在这方面是非常棘手的!通常使用“外部”表中的列进行过滤,例如Competition。但是您不希望这样做;您希望对左连接的表进行过滤。尝试按如下方式重写:

代码语言:javascript
复制
SELECT Competition.CompetitionID, Competition.CompetitionName,   Competition.CompetitionStartDate  
FROM Competition  
LEFT JOIN PicksPoints ON (Competition.CompetitionID = PicksPoints.CompetitionID AND UserID = 1)
WHERE 
PicksPoints.PicksPointsID is null  

有关这方面的更多信息,请阅读此nice post

但是,需要注意的是,在性能方面,使用子查询或左连接时会遇到一些麻烦。

使用子查询,您会遇到麻烦,因为直到5.6 (已经完成了一些不错的工作),MySQL在优化内部查询方面做得非常糟糕,而且您的子查询可能会多次执行。

使用LEFT JOIN,您就有麻烦了,因为LEFT JOIN规定了从左到右连接的顺序。然而,您的过滤是在正确的表上,这意味着您将不能使用索引来过滤USerID = 1条件(否则,您将丢失用于连接的索引)。

票数 1
EN

Stack Overflow用户

发布于 2012-07-21 12:20:44

这是两个不同的查询。第一个查询查找与用户id1相关联的比赛(通过PicksPoints表),第二个查询将其与另外具有空PicksPointsID的与用户id1相关联的行连接起来。

第二个查询是空的,因为您正在连接一个名为PicksPoints的表,并且在连接结果中查找PicksPointsID为null的行。只有在以下情况下才会发生这种情况

  1. 第二个表中有一行的PickPointsID为null,且竞争id与第一个表中的竞争id匹配,或者
  2. 第二个表中参与联接的所有列都为null,因为第一个表中存在第二个表中没有出现的竞争id。

因为PicksPointsID听起来确实像一个主键,所以出现的是第二种情况。因此,PickPointsID中的所有列都是空的,where子句(UserID=1 and PicksPoints.PicksPointsID is null)将始终为false,并且结果将为空。

普通的左连接应该适合您。

代码语言:javascript
复制
select c.CompetitionID, c.CompetitionName, c.CompetitionStartDate  
from Competition c
left join PicksPoints p
on (c.CompetitionID = p.CompetitionID)
where p.UserID <> 1

and替换最后的where (生成一个复杂的join子句)也可以。我将留给您来分析每个查询的计划。:)

我个人并不认为有必要进行is null测试。Shlomi Noach链接的文章很棒,你可以在里面找到一些技巧来帮助你做到这一点。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11589386

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档