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 JOIN
ed 记录放在底部的方式更改顺序,例如:
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
当我执行此 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 JOIN
ed 记录放在底部的方式更改顺序,例如:
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