在我的数据库中,我收集了在蒸汽期间请求的歌曲。每首歌都是由已知用户请求的。我想实现每个用户可以为所请求的歌曲评分的功能。鉴于这种情况,您可以查看我的数据库模型:
现在我想选择一个由其ID识别的特定歌曲请求,以及该歌曲的平均评分以及歌曲的评分频率。为此,我想使用以下SQL:
SELECT
sr.id,
sr.user_id,
sr.title,
sr.link,
sr.request_time,
COALESCE(AVG(r.rating), 0) AS rating,
COUNT(r.sr_id) AS votes
FROM song_requests sr LEFT OUTER JOIN sr_ratings r
ON sr.id = r.sr_id
WHERE sr.id = 12345;
在我的song_requests表中,我有以下数据:
在sr_ratings表中有一些示例评级:
如果我用
执行SQLsr.id = 1
在WHERE子句中我得到以下预期结果:
如果我现在使用不存在的song_request的id
sr.id = 12345
我会得到以下结果:
我希望查询找不到任何结果,因为id不存在。我在哪里错了?我需要做些什么才能获得理想的结果?
答案 0 :(得分:3)
这里有很多问题。首先,您显然正在使用MySQL,因为代码几乎在任何其他数据库中都是假的。您有一个聚合函数,以及非聚合列,没有GROUP BY
子句。
我猜你想要这样的东西:
SELECT sr.id, sr.user_id, sr.title, sr.link, sr.request_time,
COALESCE(AVG(r.rating), 0) AS rating,
COUNT(r.sr_id) AS votes
FROM song_requests sr LEFT OUTER JOIN
sr_ratings r
ON sr.id = r.sr_id
WHERE sr.id = 12345
GROUP BY sr.id, sr.user_id, sr.title, sr.link, sr.request_time;
瞧!您会发现这可以解决您的问题。这将不返回任何行。
您的代码返回一行,因为它是一个没有GROUP BY
的聚合查询。即使没有匹配,它也总是返回一行。事实证明,问题不在于LEFT JOIN
;这是GROUP BY
的错误用法。
答案 1 :(得分:0)
LEFT JOIN
或LEFT OUTER JOIN
关键字返回左表中的所有记录,以及右表中匹配的记录。如果没有匹配,结果是来自右侧的NULL
。
您可以在IS NOT NULL
声明中尝试CASE
。还有另一个问题可以回答你的问题。 How to select all values and hide NULL values in SQL?