【问题标题】:SQL COUNT return multiple rowsSQL COUNT 返回多行
【发布时间】:2022-10-14 22:41:54
【问题描述】:

我有这两个表:

tblCommentReactions

id Liked CommentID
1 0 1
2 1 1
3 1 1
4 0 2

1是喜欢,0是不喜欢。

tbl评论:

id userID message
1 1 message 1
2 1 message 2
3 2 message 1

我尝试选择所有 cmets 并计算不喜欢和喜欢并在同一行中给出结果。

SELECT c.ID as CommentID, c.message,
COUNT(case when Liked = 1 AND r.CommentID = c.ID then 1 else null end) as likes, 
COUNT(case when Liked = 0 AND r.CommentID = c.ID then 1 else null end) as dislikes
FROM tblcomments as c LEFT JOIN tblcommentreactions as r ON c.ID = r.CommentID
WHERE c.userID = 1;

预期输出应该是:

CommentID message likes dislikes
1 message 1 2 1
2 message 2 0 1

在我的 Return 上,它会计算所有内容,并且只返回第一条消息。你能告诉我我需要改变我的请求,以获得我的预期输出吗?

【问题讨论】:

  • 您使用的是哪个 RDBMS?我猜是 MySQL,因为如果没有 GROUP BY c.ID, c.message(或者有时是 GROUP BY c.ID),大多数 RDBMS 都不会允许这样做。
  • 在您的案例语句“AND r.CommentID = c.ID”中是多余的,因为它由 LEFT JOIN 处理。您也可以使用 ELSE 0 因为它在 COUNT 函数中

标签: sql


【解决方案1】:

您的查询中有两个问题:

  • 在SELECT 子句中存在非聚合字段的情况下,您没有GROUP BY 子句,这将在最好的情况下为您带来由DBMS 触发的错误,没有错误但随机/微妙的语义错误最糟糕的一个。
  • 您正试图在应用聚合之前过滤您的行(WHERE 条件)。

为了解决:

  • 第一个问题,需要在GROUP BY子句中加上两个缺失的选中字段,即“c.ID“ 和 ”c.消息"
  • 第二个问题,你需要将你当前的WHERE子句转换为HAVING一个(只要这个在聚合完成后应用)并添加选中字段,即“c.用户ID",在GROUP BY 子句中,只要它是与SELECT 子句中的字段一起选择的字段。
SELECT c.ID as CommentID, 
       c.message,
       COUNT(CASE WHEN Liked = 1 THEN 1 END) AS likes, 
       COUNT(CASE WHEN Liked = 0 THEN 1 END) AS dislikes
FROM      tblComments         AS c 
LEFT JOIN tblCommentReactions AS r 
       ON c.ID = r.CommentID
GROUP BY c.ID,
         c.message,
         c.userID
HAVING c.userID = 1

对不需要“AND r.CommentID = c.ID“正如在 cmets 部分中已经指出的那样,但也是非必需的”否则为空" 条件,PostgreSQL 将其视为此构造的默认值。

这是 MySQL 中的demo,尽管这应该或多或少在最常见的 DBMS 中起作用。

【讨论】:

    【解决方案2】:

    尝试使用 group by 子句,例如

    select cr.CommentID ,c.message,
        COUNT(case when Liked = 1 AND cr.CommentID = c.ID then 1 else null end) as likes ,
        COUNT(case when Liked = 0 AND cr.CommentID = c.ID then 1 else null end) as dislikes
        
        from [tblCommentReactions] cr inner join tblComments c on cr.CommentID = c.id
        
        group by cr.CommentID , c.message
    

    【讨论】:

      猜你喜欢
      • 2014-07-23
      • 2021-09-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-22
      • 2018-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多