MySQL left join排除不匹配的记录?

MySQL left join excludes non-matching records?

当我执行此 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

请注意,我注释掉了 select(聚合)和左连接中的最后一列。但是,当我在 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,有些人认为这是导致问题的原因。我删除了限制条款,但问题仍然存在,因此与它无关。现在我已经从原来的 post 中删除了 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

(注意table中只有10条记录。)

重要提示:请注意我的 select 语句中的聚合:ifnull(sum(pv.UpVote),0) - ifnull(sum(pv.DownVote),0) AS NetVotes

您的问题不是 LEFT JOIN,而是 LIMIT 0,10

所以要修复它,您可以从查询中删除 LIMIT

或者您可以尝试将 LEFT JOINed 记录放在底部的方式更改顺序,例如:

SELECT 
  h.ID AS ProductID, 
  h.ProductTitle, 
  u.Username, 
  ht.ProductType, 
  hd.Difficulty, 
  hv.NetVotes
FROM Products h 
LEFT JOIN Users u 
ON h.UserID = u.ID 
LEFT JOIN ProductTypes ht 
ON h.ProductTypeID = ht.ID 
LEFT JOIN ProductDifficulties hd 
ON h.ProductDifficultyID = hd.ID 
LEFT JOIN (
   SELECT
      ProductID,
      SUM(IFNULL(UpVote,0) - IFNULL(hv.DownVote,0)) AS NetVotes
   FROM
      ProductVotes
   GROUP BY ProductID
) hv
ON h.ID = hv.ProductID
LIMIT 0, 10;
select h.ID AS ProductID, h.ProductTitle, u.Username, ht.ProductType, hd.Difficulty, 
(select ifnull(sum(pv.UpVote),0) - ifnull(sum(pv.DownVote),0) from ProductVotes pv where h.ID = pv.ProductID ) 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