SELECT查找不存在的id的结果

时间:2017-05-09 10:38:51

标签: mysql sql select join

在我的数据库中,我收集了在蒸汽期间请求的歌曲。每首歌都是由已知用户请求的。我想实现每个用户可以为所请求的歌曲评分的功能。鉴于这种情况,您可以查看我的数据库模型:

Database model

现在我想选择一个由其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表中,我有以下数据:

song_request row

在sr_ratings表中有一些示例评级:

sr_ratings example

如果我用

执行SQL
sr.id = 1 
在WHERE子句中

我得到以下预期结果:

query_ok_result

如果我现在使用不存在的song_request的id

sr.id = 12345

我会得到以下结果:

query_bad_result

我希望查询找不到任何结果,因为id不存在。我在哪里错了?我需要做些什么才能获得理想的结果?

2 个答案:

答案 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 JOINLEFT OUTER JOIN关键字返回左表中的所有记录,以及右表中匹配的记录。如果没有匹配,结果是来自右侧的NULL

您可以在IS NOT NULL声明中尝试CASE。还有另一个问题可以回答你的问题。 How to select all values and hide NULL values in SQL?