(MySQL)按字段分组并选择 COUNT(field) 和分组行数

Posted

技术标签:

【中文标题】(MySQL)按字段分组并选择 COUNT(field) 和分组行数【英文标题】:(MySQL) Group by field and select both COUNT(field) and number of grouped rows 【发布时间】:2017-01-08 10:13:10 【问题描述】:

我有一个多对多表,其结构大致如下:

id  | obj
----+---------
1   | 27
1   | 42
2   | 32
2   | 42
2   | 162
2   | 89
3   | 2
3   | 209

基本上,该表将任意数量的对象 (obj) 与任意数量的集合 (id) 相关联。

我正在尝试从该表中返回SELECT,该方式将返回按id 分组的GROUP BY 子句中的行数,以及分组的行数分组按每组中的行数。

如果我只是简单地做SELECT COUNT(id) FROM table GROUP BY id,我自然会得到以下结果:

id  | COUNT(id)
----+---------
1   | 2
2   | 4
3   | 2

也就是说,COUNT(id) = 4 有一行,COUNT(id) = 2 有两行。到目前为止,一切都很好。但不是我在这里寻找的。​​p>

我需要的是:对于COUNT(id)(在本例中为 2 和 4)返回的每个不同的值,选择 COUNT(id) 和匹配该值的行数COUNT(id) 列(在本例中分别为 2 和 1:2 行具有 COUNT(id) = 2,1 行具有 COUNT(id) = 4)。

换句话说,从上表中,我想要这个:

id_cnt | grp_cnt
-------+---------
2      | 2
4      | 1

– 因为按id 对表进行分组,所以您会得到两个 行,其中COUNT(id) 为2(ids 1 和3); 一个行,其中COUNT(id) 为 4 (id 2)。

尽我所能,但我无法在一个查询中找到一种方法。

我能想到的最接近的东西是这样的:

SELECT COUNT(*), id_cnt FROM table JOIN (SELECT COUNT(id) id_cnt FROM table GROUP BY id) a

——但这给出了:

count(*) | id_cnt
---------+---------
21100    | 2

——我承认这让我有点困惑。

可以吗?

 

(奇怪的是,我找不到这个问题已经被问过了——这肯定以前一定被问过?也许我只是在搜索查询的措辞上很糟糕……)

【问题讨论】:

如果你按 id 分组,你会得到 3 行。在这里帮不了你 @Michael 是的,完全正确。你会得到三行,其中一行有COUNT(id) = 4,两行有COUNT(id) = 2。我要做的是,对于COUNT(id) 的每个值,返回具有该值的行数。 给我看看你的 sql 老兄 @Michael SQL 在过去 30 分钟内更改了大约 50 次,大多数排列导致各种语法错误——这是问题的一部分。我现在更新了问题以更详细地解释。 也许SELECT id, COUNT(id) as idcnt ,COUNT(*) as rowcnt FROM table GROUP BY id 【参考方案1】:

您可以围绕您的第一个分组查询添加另一个级别的分组。

SELECT id_cnt, COUNT(*) AS grp_cnt 
FROM (
    SELECT COUNT(*) AS id_cnt 
    FROM test.test GROUP BY id) id_cnts
GROUP BY id_cnt;

【讨论】:

太棒了!我的大脑现在太疲惫了,甚至无法正确理解为什么我的非常相似的尝试没有奏效(我加入了子查询表而不是直接从中选择......所以不知何故 [在此处插入 mysql 数学/魔术] 夸大了行数结果集非常可笑)。但这确实有效,并且完全符合预期。非常感谢!你和 scaisEdge 发布了几乎相同的答案,但你比 scaisEdge 快了 35 秒,所以我会给你打勾。 :-) @Michael 这对我来说似乎并不生气。也许我也很生气。【参考方案2】:

这样就可以通过id获取cont了

  select id, count(*) as ctn
  from table 
  group by id

与第二级计数相同计数的计数

 select ctn, count(*)
 from ( select id, count(*) as ctn
        from table 
        group by id) t
 group by ctn

【讨论】:

@MichaelRudnerEvanchik 阅读第一个样本似乎这就是 OP 正在寻找的......(我希望) @scaisEdge 这确实正是我想要的。但是,由于 Don't Panic 比您快一点(使用令人印象深刻的相同解决方案),因此我接受了他的回答,非常感谢你们俩。 :-)

以上是关于(MySQL)按字段分组并选择 COUNT(field) 和分组行数的主要内容,如果未能解决你的问题,请参考以下文章

mysql按字段分组并获取每个分组按照某个字段排序的前三条

ElasticSearch 按多个字段分组

请教各位大牛关于mysql按时间段分组查询的问题。

COUNT分组条件去重的sql统计语句示例(mysql)

分组和计数mysql

MySQL分组链接的使用