0

此查询显示正确的结果,但是在执行 EXPLAIN 时,它会将其列为“依赖子查询”,我被认为是错误的?

SELECT Competition.CompetitionID, Competition.CompetitionName,     Competition.CompetitionStartDate  
FROM Competition  
WHERE CompetitionID NOT   
IN (  
SELECT CompetitionID  
FROM PicksPoints  
WHERE UserID =1    
)

我尝试将查询更改为:

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 行。与实际有效的第一个查询相比,上述内容有什么问题?

4

2 回答 2

1

秒查询不能产生行:它声称:

WHERE UserID =1  
and PicksPoints.PicksPointsID is null 

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

WHERE PicksPoints.UserID =1  
and PicksPoints.PicksPointsID is null 

因此,一方面,您要求在PicksPointswhere上的行UserId = 1,但又一次您希望该行首先不存在。你能看到失败吗?

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

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  

有关这方面的更多信息,请阅读这篇不错的帖子

但是,作为附加说明,在性能方面你遇到了一些麻烦,使用子查询或左连接。

使用子查询你会遇到麻烦,因为高达5.6(已经完成了一些好的工作),MySQL 在优化内部查询方面非常糟糕,并且你的子查询预计会执行多次。

由于 a规定了从左到右的连接顺序,因此LEFT JOIN您遇到了麻烦。LEFT JOIN然而,您的过滤器位于正确的表上,这意味着您将无法使用索引来过滤USerID = 1条件(或者您将无法使用索引来进行连接)。

于 2012-07-21T04:48:54.973 回答
0

这是两个不同的查询。第一个查询查找与用户 id 1 关联的竞争(通过PicksPoints表),第二个查询与与用户 id 1 关联的那些行连接,这些行具有 null PicksPointsID

第二个查询结果为空,因为您正在连接一个名为的表PicksPoints,并且您正在查找连接结果中PicksPointsID为空的行。这只能发生在

  1. 第二个表有一个空行和一个PickPointsID 第一个表中的竞争 id 匹配的竞争 id,或者
  2. 第二个表中对连接的贡献的所有列都是空的,因为第一个表中有一个没有出现在第二个表中的竞争 id。

由于PicksPointsID听起来确实像主键,因此出现了案例 2。所以来自的所有列PickPointsID都是空的,你的 where 子句 ( UserID=1 and PicksPoints.PicksPointsID is null) 将永远是假的,你的结果将是空的。

一个普通的左连接应该适合你

select c.CompetitionID, c.CompetitionName, c.CompetitionStartDate  
from Competition c
left join PicksPoints p
on (c.CompetitionID = p.CompetitionID)
where p.UserID <> 1

whereand(制作复杂的连接子句)替换final也可能有效。我将留给您分析每个查询的计划。:)

我个人并不相信is null测试的必要性。Shlomi Noach 链接到的文章非常好,您可能会在其中找到一些提示来帮助您。

于 2012-07-21T04:20:43.730 回答