我有以下SQL查询:
SELECT tblBooks.bookID,
tblBooks.title,
tblBooks.author,
tblBooks.coverImage,
ROUND(ROUND(tblReviews.rating * 2) / 2, 1) AS rating
FROM tblBooks
LEFT JOIN tblReviews
ON tblBooks.bookID = tblReviews.bookID
LEFT JOIN tblMembers
ON tblReviews.userID = tblMembers.userID
WHERE tblReviews.bookID IS NOT NULL
ORDER BY rating DESC
LIMIT 0, 40
我想查询数据库并返回平均评分,因此,如果一本书已经被审核了6次,则总计来自6个用户的每个评级并计算平均值。目前只返回最新的评级。当我将此行更改为:
ROUND(ROUND(AVG(tblReviews.rating) * 2) / 2, 1) AS rating
总共只返回一个结果,所以显然出现了问题,但我不知道是什么。
如果有人能说清楚这一点,我认为这会与我的联系有关。
答案 0 :(得分:3)
你需要像这样使用group by
:
SELECT tblBooks.bookID, tblBooks.title, tblBooks.author, tblBooks.coverImage,
AVG(tblReviews.rating) as avgRating
FROM tblBooks
LEFT JOIN tblReviews
ON tblBooks.bookID = tblReviews.bookID
WHERE tblReviews.bookID IS NOT NULL
group by tblBooks.bookID, tblBooks.title, tblBooks.author, tblBooks.coverImage
ORDER BY avgrating DESC
您的查询似乎没有使用Members表中的任何信息,因此我将其删除。它甚至不基于它进行过滤,因为您使用的是left join
。
答案 1 :(得分:1)
为什么不使用AVG
?
SELECT tblBooks.bookID,
tblBooks.title,
tblBooks.author,
tblBooks.coverImage,
AVG(tblReviews.rating) AS rating
FROM tblBooks
LEFT JOIN tblReviews
ON tblBooks.bookID = tblReviews.bookID
LEFT JOIN tblMembers
ON tblReviews.userID = tblMembers.userID
WHERE tblReviews.bookID IS NOT NULL
Group By tblBooks.bookID, tblBooks.title, tblBooks.author, tblBooks.coverImage
ORDER BY rating DESC
LIMIT 0, 40
在MYSQL中,您不需要按所有列进行分组,尽管这是一个很好的做法,因为您在使用其他RDMS时需要这样做。
答案 2 :(得分:1)
您也不需要WHERE
。您基本上正在进行INNER
加入:
SELECT t.bookID,
t.title,
t.author,
t.coverImage,
AVG(r.rating) AS rating
FROM tblBooks AS t
JOIN tblReviews AS r
ON b.bookID = r.bookID
GROUP BY t.bookID
-- , t.title, t.author, t.coverImage
ORDER BY rating DESC
LIMIT 40 ;
注意:仅当GROUP BY t.bookID
是bookID
中的主键(或具有唯一约束)时,仅使用tblBooks
(并且不存在其他列)才会给出正确的结果。所有其他DBMS都不允许这样做(除了Postgres,但该产品已正确实现了该功能,并确实检查其他列是否依赖于分组列)。 MySQL根本没有检查,因此在许多情况下它会产生错误的结果。
它还取决于sql_mode
设置,上述内容是否会正常运行。
您也可以先分组然后再加入。这是有效的SQL,不会出现错误结果:
SELECT t.bookID,
t.title,
t.author,
t.coverImage,
g.rating
FROM tblBooks AS t
JOIN
( SELECT r.bookID,
AVG(r.rating) AS rating
FROM tblReviews AS r
GROUP BY r.bookID
) AS g
ON b.bookID = r.bookID
ORDER BY rating DESC
LIMIT 40 ;
答案 3 :(得分:0)
我认为你缺少的是
GROUP BY tblBooks.bookID, tblBooks.title, tblBooks.author, etc...
AVG是一个汇总数据的聚合函数,使用GROUP BY创建聚合组。
答案 4 :(得分:0)
试试这个:
...
WHERE tblReviews.bookID IS NOT NULL
GROUP BY tblBooks.bookID
ORDER BY rating DESC
LIMIT 0, 40
干杯。