【问题标题】:Can this query, which groups users by amount of comments posted, be simplified?这个按评论数量对用户进行分组的查询可以简化吗?
【发布时间】:2020-04-26 22:42:03
【问题描述】:

此查询中使用了两个表,结果中最重要的是到目前为止已发布或未发布任何 cmets 的用户数。表user当然有列id,也就是表comment中的外键,由列user_id标识。

第一个超级简单的查询根据用户到目前为止是否有任何 cmets 对用户进行分组。它输出两行(一行包含拥有 cmets 的用户数,一行包含没有 cmets 的用户数),两列(用户数,以及他们是否发布了任何 cmets)。

SELECT 
    COUNT(id) AS user_count, 
    IF( id IN ( SELECT user_id FROM `comment` ), 1, 0) AS has_comment
FROM `user`
GROUP BY has_comment

此处的输出示例如下:

+------------+-------------+
| user_count | has_comment |
+------------+-------------+
| 150        | 0           |
| 140        | 1           |
+------------+-------------+

现在我的问题来了。我想在这里获得更多信息,将这些用户分为 3 个组:

  1. 未发布任何 cmets 的用户
  2. 发布少于 10 个 cmets 的用户
  3. 已发布 10 个或更多 cmets 的用户

我知道如何为此目的编写的最佳查询如下,它有效,但不幸的是运行 4 个子查询并有 2 个派生表:

SELECT 
   COUNT(id) AS user_count,
   CASE
      WHEN id IN ( SELECT user_id FROM ( SELECT COUNT(user_id) AS comment_count, user_id FROM `comment` GROUP BY user_id HAVING comment_count >= 10 ) AS a) THEN '10 or more'
      WHEN id IN ( SELECT user_id FROM ( SELECT COUNT(user_id) AS comment_count, user_id FROM `comment` GROUP BY user_id HAVING comment_count < 10 ) AS b) THEN 'less than 10'
      ELSE 'none'
   END AS has_comment
FROM `user`
GROUP BY has_comment

这里的输出示例如下:

+------------+-------------+
| user_count | has_comment |
+------------+-------------+
| 150        | none        |
| 130        | less than 10|
| 100        | 10 or more  |
+------------+-------------+

第二个查询;能不能写得更简单、更高效,还能产生同样的结果? (甚至可能扩展到更多这样的“群体”)

【问题讨论】:

标签: mysql sql join group-by count


【解决方案1】:

您可以使用两个级别的聚合:

select
    count(*) no_users,
    case
        when no_comments = 0 then 'none'
        when no_comments < 10 then 'less than 10'
        else '10 or more'
    end has_comment
from (
    select 
        u.id, 
        (select count(*) from comments c where c.user_id = u.id) no_comments
    from users u
) t
group by has_comment
order by no_comments

子查询计算每个用户有多少 cmets(你也可以用 left join 和聚合来表示);然后,外部查询根据 cmets 的数量对用户进行分类和计数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-01
    • 1970-01-01
    • 2019-02-24
    • 1970-01-01
    • 2011-08-21
    相关资源
    最近更新 更多