这个查询显示了正确的结果,但在执行解释时,它将其列为"Dependant SubQuery“,我认为这是错误的?
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行。与第一个实际工作的查询相比,上面的查询有什么问题?
发布于 2012-07-21 12:48:55
秒查询不能生成行:它声明:
WHERE UserID =1
and PicksPoints.PicksPointsID is null 但为了澄清,我重写如下:
WHERE PicksPoints.UserID =1
and PicksPoints.PicksPointsID is null 因此,一方面,您在PicksPoints where 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 有关这方面的更多信息,请阅读此nice post。
但是,需要注意的是,在性能方面,使用子查询或左连接时会遇到一些麻烦。
使用子查询,您会遇到麻烦,因为直到5.6 (已经完成了一些不错的工作),MySQL在优化内部查询方面做得非常糟糕,而且您的子查询可能会多次执行。
使用LEFT JOIN,您就有麻烦了,因为LEFT JOIN规定了从左到右连接的顺序。然而,您的过滤是在正确的表上,这意味着您将不能使用索引来过滤USerID = 1条件(否则,您将丢失用于连接的索引)。
发布于 2012-07-21 12:20:44
这是两个不同的查询。第一个查询查找与用户id1相关联的比赛(通过PicksPoints表),第二个查询将其与另外具有空PicksPointsID的与用户id1相关联的行连接起来。
第二个查询是空的,因为您正在连接一个名为PicksPoints的表,并且在连接结果中查找PicksPointsID为null的行。只有在以下情况下才会发生这种情况
PickPointsID为null,且竞争id与第一个表中的竞争id匹配,或者因为PicksPointsID听起来确实像一个主键,所以出现的是第二种情况。因此,PickPointsID中的所有列都是空的,where子句(UserID=1 and PicksPoints.PicksPointsID is null)将始终为false,并且结果将为空。
普通的左连接应该适合您。
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链接的文章很棒,你可以在里面找到一些技巧来帮助你做到这一点。
https://stackoverflow.com/questions/11589386
复制相似问题