【问题标题】:Getting percentage of "Count(*)" to the number of all items in "GROUP BY"获取“Count(*)”占“GROUP BY”中所有项目数的百分比
【发布时间】:2026-01-01 06:00:01
【问题描述】:

假设我需要“某个类别的可用项目数”与“所有项目数”的比率。请考虑这样的 MySQL 表:

/*

mysql> select * from Item;
+----+------------+----------+
| ID | Department | Category |
+----+------------+----------+
|  1 | Popular    | Rock     |
|  2 | Classical  | Opera    |
|  3 | Popular    | Jazz     |
|  4 | Classical  | Dance    |
|  5 | Classical  | General  |
|  6 | Classical  | Vocal    |
|  7 | Popular    | Blues    |
|  8 | Popular    | Jazz     |
|  9 | Popular    | Country  |
| 10 | Popular    | New Age  |
| 11 | Popular    | New Age  |
| 12 | Classical  | General  |
| 13 | Classical  | Dance    |
| 14 | Classical  | Opera    |
| 15 | Popular    | Blues    |
| 16 | Popular    | Blues    |
+----+------------+----------+
16 rows in set (0.03 sec)

mysql> SELECT Category, COUNT(*) AS Total
    -> FROM Item
    -> WHERE Department='Popular'
    -> GROUP BY Category;
+----------+-------+
| Category | Total |
+----------+-------+
| Blues    |     3 |
| Country  |     1 |
| Jazz     |     2 |
| New Age  |     2 |
| Rock     |     1 |
+----------+-------+
5 rows in set (0.02 sec)

*/

我需要的基本上是一个类似于这个的结果集:

/*
+----------+-------+-----------------------------+
| Category | Total | percentage to the all items | (Note that number of all available items is "9")
+----------+-------+-----------------------------+
| Blues    |     3 |                          33 | (3/9)*100
| Country  |     1 |                          11 | (1/9)*100
| Jazz     |     2 |                          22 | (2/9)*100
| New Age  |     2 |                          22 | (2/9)*100
| Rock     |     1 |                          11 | (1/9)*100
+----------+-------+-----------------------------+
5 rows in set (0.02 sec)

*/

如何在单个查询中实现这样的结果集?

提前致谢。

【问题讨论】:

  • 我不知道如何在查询中执行,但为什么不在处理结果的代码中执行呢?
  • 不幸的是,我需要在一个查询中完成它以适应我的 API。尽管如此,我还是在 * 上找到了类似的问答。请参阅下面的答案。

标签: mysql


【解决方案1】:
SELECT Category, COUNT(*) AS Total , (COUNT(*) / (SELECT COUNT(*) FROM Item WHERE Department='Popular')) * 100 AS 'Percentage to all items', 
FROM Item
WHERE Department='Popular'
GROUP BY Category;

我不确定 MySql 语法,但您可以使用如图所示的子查询。

【讨论】:

  • 是的,你是对的,我也找到了这个话题:*.com/questions/1576370/… 看起来内部查询即使重复,也可能不会花费太多时间,这要归功于 MySQL 优化等。
  • 非常感谢。这是完美的。
  • 不应该为了得到百分比而颠倒除法吗? ((SELECT COUNT(*) FROM Item WHERE Department='Popular') / COUNT(*)) * 100
  • 它有效,但我不喜欢重复 where 子句
【解决方案2】:

应该这样做:

SELECT I.category AS category, COUNT(*) AS items, COUNT(*) / T.total * 100 AS percent
FROM Item as I,
     (SELECT COUNT(*) AS total FROM Item WHERE Department='Popular') AS T
WHERE Department='Popular'
GROUP BY category;

【讨论】:

  • FROM 子句中缺少逗号,COUNT(*) 没有列别名
【解决方案3】:
SET @total=0;

SELECT Category, count(*) as Count, count(*) / @total * 100 AS Percent FROM (
    SELECT Category, @total := @total + 1
    FROM Item
    WHERE Department='Popular') temp
GROUP BY Category;

这样做的一个好处是您不必复制WHERE 条件,这是下次有人来更新条件时的定时炸弹,但没有意识到它在两个不同的地方.

避免重复的WHERE 条件也提高了可读性,尤其是如果您的WHERE 更复杂(具有多个连接等)。

【讨论】:

  • 内联变量赋值 (:=) 在 Mysql 8 中已弃用,将被移除