根据group by查询的结果按出现次数分组
Group by number of occurrences based on the result of a group by query
想象一下 table 这样的帖子
posts
---
id
user_id
title
如果我想打印出每个用户的帖子总数,我可能会这样做
SELECT user_id, COUNT(*) as total_posts FROM posts GROUP BY user_id
结果将是这样的:
user_id | total_posts
=====================
1 | 5
2 | 2
5 | 3
8 | 3
现在,如果我想按 total_posts 分组怎么办?所以我正在寻找这样的结果:
total_posts | number_of_users
=============================
5 | 1
2 | 1
3 | 2
是否可以通过 MySQL 执行此操作?我目前正在通过使用 Laravel 的集合来解决这个问题,但是它需要映射 user_id | total_posts
table 的每一行,这可能很大,因此可能会占用内存。
您需要 2 个聚合级别:
SELECT total_posts,
COUNT(*) number_of_users
FROM (
SELECT user_id,
COUNT(*) total_posts
FROM posts
GROUP BY user_id
) t
GROUP BY total_posts
ORDER BY total_posts DESC;
或者,对于 MySql 8.0+:
SELECT DISTINCT
COUNT(*) total_posts,
COUNT(*) OVER (PARTITION BY COUNT(*)) number_of_users
FROM posts
GROUP BY user_id
ORDER BY total_posts DESC;
查看简化版 demo.
如果有人在 Laravel 中寻找解决方案,这就是我最终得到的
$posts = DB::query()
->fromSub(function ($query) {
$query->from('posts')
->selectRaw('user_id, COUNT(*) as total_posts')
->groupBy('user_id');
}, 't')
->selectRaw('total_posts, COUNT(*) number_of_users')
->groupBy('total_posts')
->orderBy('total_posts', 'asc')
->get();
想象一下 table 这样的帖子
posts
---
id
user_id
title
如果我想打印出每个用户的帖子总数,我可能会这样做
SELECT user_id, COUNT(*) as total_posts FROM posts GROUP BY user_id
结果将是这样的:
user_id | total_posts
=====================
1 | 5
2 | 2
5 | 3
8 | 3
现在,如果我想按 total_posts 分组怎么办?所以我正在寻找这样的结果:
total_posts | number_of_users
=============================
5 | 1
2 | 1
3 | 2
是否可以通过 MySQL 执行此操作?我目前正在通过使用 Laravel 的集合来解决这个问题,但是它需要映射 user_id | total_posts
table 的每一行,这可能很大,因此可能会占用内存。
您需要 2 个聚合级别:
SELECT total_posts,
COUNT(*) number_of_users
FROM (
SELECT user_id,
COUNT(*) total_posts
FROM posts
GROUP BY user_id
) t
GROUP BY total_posts
ORDER BY total_posts DESC;
或者,对于 MySql 8.0+:
SELECT DISTINCT
COUNT(*) total_posts,
COUNT(*) OVER (PARTITION BY COUNT(*)) number_of_users
FROM posts
GROUP BY user_id
ORDER BY total_posts DESC;
查看简化版 demo.
如果有人在 Laravel 中寻找解决方案,这就是我最终得到的
$posts = DB::query()
->fromSub(function ($query) {
$query->from('posts')
->selectRaw('user_id, COUNT(*) as total_posts')
->groupBy('user_id');
}, 't')
->selectRaw('total_posts, COUNT(*) number_of_users')
->groupBy('total_posts')
->orderBy('total_posts', 'asc')
->get();