sql - 左连接 - 计数

Posted

技术标签:

【中文标题】sql - 左连接 - 计数【英文标题】:sql - left join - count 【发布时间】:2011-01-14 00:25:53 【问题描述】:

假设我有两张桌子。文章和cmets。

当我从articles表中选择列时,我还想在同一个select语句中选择文章上的cmets数量......(假设这两个表之间的公共字段是articleid)

我该怎么做?我可以完成它,但我不知道我的方法是否有效,所以我想学习正确的方法。

【问题讨论】:

【参考方案1】:

这应该更有效,因为 group by 只在 Comment 表上完成。

SELECT  
       a.ArticleID, 
       a.Article, 
       isnull(c.Cnt, 0) as Cnt 
FROM Article a 
LEFT JOIN 
    (SELECT c.ArticleID, count(1) Cnt
     FROM Comment c
    GROUP BY c.ArticleID) as c
ON c.ArticleID=a.ArticleID 
ORDER BY 1

【讨论】:

^ 如果只将计数附加到您的选择中,上面的答案是更有效/更正确的答案。【参考方案2】:

用途:

   SELECT a.articleid, 
          COUNT(*) AS num_comments
     FROM ARTICLES a
LEFT JOIN COMMENTS c ON c.articleid = a.articleid
 GROUP BY a.articleid

无论您想从ARTICLES 表中获得什么列,都必须在GROUP BY 子句中定义,因为它们没有对它们执行聚合函数。

【讨论】:

仅添加 group by 并不总是最好的做法。我看到人们在 group by 子句中使用 100 列(不是 100 列,而是很多列)编写查询,因为他们不知道如何正确使用聚合。这就是我使用子查询发布解决方案的原因。 @JonH:类似的 SQL Server(以及其他 DB)不允许您列出/返回未包装在聚合函数中的列(除非使用分析函数),而无需在 @987654325 中定义它们@ 子句。如果省略GROUP BY 子句,您根据所提供的内容在 SQL Server 上收到错误。 mysql 是唯一支持此类功能的数据库,并且它是非标准的:dev.mysql.com/doc/refman/5.0/en/group-by-hidden-columns.html 我知道我的意思是很多人不明白分组和聚合是如何工作的。我见过人们按 100 列分组只是为了得到他们认为可能是正确的结果。【参考方案3】:

应该这样做..

SELECT
   article_column_1, article_column_2, count( ct.articleid) as comments
FROM
   article_table at
   LEFT OUTER JOIN comment_table ct ON at.articleid = ct.articleid
GROUP BY 
   article_column_1, article_column_2

【讨论】:

你可能想要一个 GROUP BY。如果有人担心,如果没有加入的记录,这将正确返回 0。 le dorfier 正确 - 此查询不会在 SQL Server 上按原样运行。【参考方案4】:
    -- Working Syntax example from my environment changed to fit this context. 
SELECT a.article
    ,A.articleid
    ,(
        SELECT Count(B.articleid)
        FROM dbo.comment AS B
        WHERE A.articleid = B.articleid
        ) AS comment#
    ,(
        SELECT Count(C.articleid)
        FROM dbo.comments AS C
        WHERE A.articleid = C.articleid
        ) AS comments#
FROM dbo.article AS A;

【讨论】:

【参考方案5】:
SELECT 
       a.Article,
       a.ArticleID,
       t.COUNTOFCOMMENTS
FROM
       Article a
LEFT JOIN
       Comment c
ON c.ArticleID=a.ArticleID
LEFT JOIN
(SELECT ArticleID, COUNT(CommentID) AS COUNTOFCOMMENTS FROM Comments GROUP BY ArticleID) t
ON t.ArticleID = a.ArticleID

【讨论】:

所以添加一个非常简单的东西。 @OP - 如果需要,您也可以取出 LEFT JOIN 注释 c,我只是把它放在那里,以便您可以根据需要从 cmets 表中提取列。 由于第一个左连接,这将为每个评论返回一行。 @J***s,请阅读 @OP 的 cmets,正如我所说,您可以摆脱左连接,它可以展示 SQL 或任何关系数据库系统的强大功能。它允许用户从其他表中提取信息。这样,如果他/她不想按文章进行简单的分组,他/她可以再次获得评论信息。再次请在发帖前阅读 cmets。 @JonH,我确实阅读了 cmets - 我的意思是,如果您有 10 个 cmets 用于第 1 条,那么第 1 条将被列出 10 次,每条旁边都有 10 个计数。我认为这不是所要求的。

以上是关于sql - 左连接 - 计数的主要内容,如果未能解决你的问题,请参考以下文章

EF Core 左连接计数

Clickhouse 数组连接与左连接和计算计数

PostgreSQL - 带有错误计数输出的左连接

具有多个左连接和计数的错误计算(Laravel)

NHibernate左连接选择计数在一对多关系中

MySQL左连接计数不起作用