【发布时间】:2015-07-08 19:58:34
【问题描述】:
当我执行这个 MySQL 查询时,我得到了预期的正确结果:
select h.ID AS ProductID, h.ProductTitle, u.Username, ht.ProductType, hd.Difficulty-- , ifnull(sum(pv.UpVote),0) - ifnull(sum(pv.DownVote),0) AS NetVotes
from Products h
join Users u on h.UserID = u.ID
join ProductTypes ht on h.ProductTypeID = ht.ID
join ProductDifficulties hd
on h.ProductDifficultyID = hd.ID
-- left join ProductVotes pv
-- on h.ID = pv.ProductID
请注意,我注释掉了选择(聚合)和左连接中的最后一列。但是当我在 sql 中包含所有内容时,只会包含具有匹配 ProductVotes 记录的记录:
select h.ID AS ProductID, h.ProductTitle, u.Username, ht.ProductType, hd.Difficulty, ifnull(sum(pv.UpVote),0) - ifnull(sum(pv.DownVote),0) AS NetVotes
from Products h
join Users u on h.UserID = u.ID
join ProductTypes ht on h.ProductTypeID = ht.ID
join ProductDifficulties hd
on h.ProductDifficultyID = hd.ID
left join ProductVotes pv
on h.ID = pv.ProductID
我希望这种行为来自内部联接,而不是左联接。为什么左连接会排除没有匹配 ProductVotes 记录的记录?我怎样才能将这些包括在内,就像上面的第一个查询一样?
编辑:最初我在查询末尾有一个LIMIT 0, 10,有些人认为这是导致问题的原因。我删除了限制条款,问题仍然存在,因此与它无关。现在我从我的原始帖子中删除了LIMIT 子句,因为它无关紧要。仍在等待答案。 :-)
这是select * from ProductVotes的完整结果:
ID ProductID UserID UpVote DownVote
2 1 2 1 NULL
3 1 3 1 NULL
4 1 4 1 NULL
5 1 5 1 NULL
6 1 6 1 NULL
7 1 7 1 NULL
8 1 8 1 NULL
9 1 9 NULL 1
10 1 10 NULL 1
22 1 1 1 NULL
(请注意表中只有 10 条记录。)
重要提示:请注意我的选择语句中的聚合:ifnull(sum(pv.UpVote),0) - ifnull(sum(pv.DownVote),0) AS NetVotes
【问题讨论】:
-
可以取消限制吗?您将看到所有匹配和不匹配的行。
-
不可能。你是否缩短了陈述?第二条语句不能返回少于 1 条语句的行
-
不分投票表中有多少行。即使它是空的,第二条语句也不能产生比第一条语句少的行。你确定你没有在某处过滤结果吗?
-
第二个查询正好返回 1 行,它是 ProductID 为 1 的行。它的行为就像一个内部连接。我以前从未见过这种情况,我使用 MySQL 已经 12 年了。我很困惑。
-
内连接会返回 10 行 :) 因为投票表中有 10 个 id 为 1 的产品。