我有一张 table ,里面装满了用户写的品酒笔记,还有一张 table ,里面保存着其他用户对每个品酒笔记的评分。
显示由您尚未评分的其他用户撰写的所有注释的查询如下所示:
SELECT tastingNotes.userID, tastingNotes.beerID, tastingNotes.noteID, tastingNotes.note, COALESCE(sum(tasteNoteRate.Score), 0) as count,
CASE
WHEN tasteNoteRate.userVoting = 1162 THEN 1
ELSE 0
END AS userScored
FROM tastingNotes
left join tasteNoteRate on tastingNotes.noteID = tasteNoteRate.noteID
WHERE tastingNotes.userID != 1162
Group BY tastingNotes.noteID
HAVING userScored < 1
ORDER BY count, userScored
用户 1162 已为注释 113 编写了注释。在tasteNoteRate 表中,它显示为:
noteID | userVoting | score
113 1162 0
但每次运行上述查询时仍然返回......
最佳答案
MySQL 允许您使用 group by
以一种相当特殊的方式而不提示,请参阅 documentation :
If ONLY_FULL_GROUP_BY is disabled, a MySQL extension to the standard SQL use of GROUP BY permits the select list, HAVING condition, or ORDER BY list to refer to nonaggregated columns even if the columns are not functionally dependent on GROUP BY columns. [...] In this case, the server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate, which is probably not what you want.
此行为是 MySQL 5.7 之前的默认行为。
在您的情况下,这意味着,如果 tasteNoteRate
中有不止一行对于特定的noteID
,所以如果其他人已经投票支持该注释,userScored
,正在使用 tasteNoteRate.userVoting
如果没有聚合函数,将基于随机行 - 可能是错误的。
您可以使用聚合来解决这个问题:
select ...,
max(CASE
WHEN tasteNoteRate.userVoting = 1162 THEN 1
ELSE 0
END) AS userScored
from ...
或者,由于比较结果(与 null
以外的其他值)为 1 或 0,因此您还可以使用较短的版本:
select ...,
coalesce(max(tasteNoteRate.userVoting = 1162),0) AS userScored
from ...
要准备升级到 MySQL 5.7(并启用 ONLY_FULL_GROUP_BY
),您还应该已经 group by
select
中的所有非聚合列-列表:group by tastingNotes.userID, tastingNotes.beerID, tastingNotes.noteID, tastingNotes.note
.
编写查询(以及其他查询)的另一种方式是对 tastingNoteRates
进行分组。在子查询中,因此您不必 group by
tastingNotes
的所有列:
select tastingNotes.*,
coalesce(rates.count, 0) as count,
coalesce(rates.userScored,0) as userScored
from tastingNotes
left join (
select tasteNoteRate.noteID,
sum(tasteNoteRate.Score) as count,
max(tasteNoteRate.userVoting = 1162) as userScored
from tasteNoteRate
group by tasteNoteRate.noteID
) rates
on tastingNotes.noteID = rates.noteID and rates.userScored = 0
where tastingNotes.userID != 1162
order by count;
这还允许您通过更改 rates.userScored = 0
来获取用户投票的注释在 on
-条款= 1
(或删除它以获得两者)。
关于mySQL 返回不应该的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42639328/