简体   繁体   English

MySQL-计算每组中的行数

[英]MySQL - Count number of rows in each group

I have a SQL table user_game which contains the games that a user owns: 我有一个SQL表user_game ,其中包含用户拥有的游戏:

| id | user_id | game_id |
|----|---------|---------|
| 83 | 1       | 1       |
| 84 | 1       | 2       |
| 85 | 1       | 3       |
| 86 | 2       | 2       |
| 87 | 2       | 3       |
| 88 | 2       | 4       |
| 89 | 3       | 2       |

I am trying to count the number of users which have 1 game, 2 games, 3 games.. etc. 我正在尝试计算拥有1个游戏,2个游戏,3个游戏等的用户数量。

User 1 has 3 games, User 2 has 3 games, and User 3 has 1 game. 用户1有3个游戏,用户2有3个游戏,用户3有1个游戏。 Therefore these are the results I want to achieve : 因此, 这些是我想要实现的结果

| no_of_games | COUNT(no_of_games) |
|-------------|--------------------|
| 1           | 1                  |
| 2           | 0                  |
| 3           | 2                  |

COUNT(no_of_games) is the number of users that have that number of games. COUNT(no_of_games)是拥有该游戏数量的用户数量。


I can individually get the number of users for each no_of_games with this query: 我可以使用此查询单独获取每个no_of_games的用户数量:

-- Select no. of users with 1 game
SELECT no_of_games, COUNT(no_of_games)
FROM
(
  -- Select no. of games each user has
  SELECT user_id, COUNT(1) as no_of_games
  FROM user_game
  GROUP BY user_id
) as A
WHERE no_of_games = 1;

which gives the results: 结果如下:

| no_of_games | COUNT(no_of_games) |
|-------------|--------------------|
| 1           | 1                  |

However I have to change the no_of_games = 1 to 2, 3, 4... manually and UNION them with this solution and I can't do it for ~60 cases. 但是,我必须手动将no_of_games = 1更改为no_of_games = 1 ...,并使用此解决方案将它们UNION起来,在大约60种情况下我做不到。

Is there a simpler way to achieve this? 有没有更简单的方法来实现这一目标?

Your problem is a bit tricky, because groups of games which do not appear in your data with a certain frequency (eg 2) will not appear in the result set just using your original table. 您的问题有点棘手,因为没有以特定频率(例如2)出现在数据中的游戏组就不会仅使用原始表就出现在结果集中。 In the query below, I use a second table called nums which simply contains the sequence 1 through 10 representing counts of number of games. 在下面的查询中,我使用第二个表nums ,该表仅包含表示游戏数的序列1到10。 By using a LEFT JOIN we can retain each game count in the final result set. 通过使用LEFT JOIN我们可以将每个游戏计数保留在最终结果集中。

SELECT t1.no_of_games,
       COALESCE(t2.no_of_games_count, 0) AS no_of_games_count
FROM nums t1
LEFT JOIN
(
    SELECT t.no_of_games, COUNT(*) AS no_of_games_count
    FROM
    (
        SELECT COUNT(*) AS no_of_games
        FROM user_game
        GROUP BY user_id
    ) t
    GROUP BY t.no_of_games
) t2
    ON t1.no_of_games = t2.no_of_games
ORDER BY t1.no_of_games

And here is the definition I used for nums : 这是我用于nums的定义:

CREATE TABLE nums (`no_of_games` int);
INSERT INTO nums (`no_of_games`)
VALUES
    (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);

Demo here: 演示在这里:

SQLFiddle SQLFiddle

You can find count of games for each user and then find count of users for each count of games. 您可以找到每个用户的游戏数量,然后找到每个游戏数量的用户数量。

select cnt no_of_games, count(*) cnt_no_of_games
from(
    select user_id, count(*) cnt
    from your_table
    group by user_id
) t group by cnt;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM