COUNT 次同一列

COUNT twice the same column

我正在尝试对具有不同条件的同一列进行两次计数,以在最后计算出某个百分比。

该列填充了从 1 到 10 的几个数字,我想知道数字大于 6 的行的百分比。

我有找回号码的想法:

SELECT number, Sum(number> 6) as number_sup_to_6 FROM table;

但我想在检索到这些数据后计算出超过 6 的数字占总数的百分比:((n>6)/n)*100

然后我从之前的 post 中得到灵感来进行计算 :

concat(round(( number_sup_to_6 /number* 100 ),2),'%') AS percentage

问题是,我不知道如何将 sql 的 2 个部分放在一起,有人可以帮助我了解如何将它们组合在一起吗?

感谢您的帮助。

试试这个:

SELECT CONCAT(ROUND(( a.sum / b.sum * 100 ), 2), '%') AS percentage
FROM 
(SELECT SUM(number) AS sum FROM table WHERE number > 6) a,
(SELECT SUM(number) AS sum FROM table) b

使用 CASE 语句

SELECT number, (number_sup_to_6/total_count)*100 AS percentage
FROM
(SELECT number, 
COUNT(CASE WHEN number > 6 THEN number ELSE NULL END) AS number_sup_to_6, 
COUNT(number) AS total_count FROM table_name 
GROUP BY number) AS a

我建议 条件聚合 的替代方案:

SELECT SUM(t.number>6) / COUNT(t.number) AS ratio_num_sup_to_six
  FROM mytable t

请注意,此 counts 具有数值大于 6 的行,counts 具有非空值的行数量。这等同于 returned 的结果:

SELECT COUNT(IF(t.number>6,1,NULL)) / COUNT(t.number) AS ratio_num_sup_to_six
  FROM mytable t

我们还可以用更符合 ANSI 标准的等价物来表达:

SELECT COUNT(CASE WHEN t.number>6 THEN 1 ELSE NULL END) 
     / COUNT(t.number) AS ratio_num_sup_to_six
  FROM mytable t

如果目标是从 number 列中存储的值中获得 总数 (值的 SUM 而不是行的 COUNT),然后是这样的:

SELECT SUM(IF(t.number>6,t.number,NULL)) / SUM(t.number) AS ratio_tot_sup_to_six
  FROM mytable t

格式化

如果我们绝对需要将比率转换为百分比以便在 SQL 查询本身(而不是客户端)中显示,那么我们可以将上面的任何表达式包装在:

  CONCAT(ROUND(( expr )*100,2),'%')

例如:

SELECT CONCAT(ROUND(( SUM(t.number>6) / COUNT(t.number) )*100,2),'%') AS pct_num_sup_to_six
  FROM mytable t

请注意,ROUND 函数中的 return 保证在小数点后包含两位数。也就是说,我们可能会得到“22.2%”或“50%”returned.

如果重要的是return小数点后两位(用于显示),我们可以使用MySQLFORMAT函数https://dev.mysql.com/doc/refman/5.7/en/string-functions.html#function_format

这将保证 return 两个(或我们想要的任意多个)十进制数字,即使数字为零。所以我们可以得到 '50.00' returned 而不是 '50'。 (FORMAT 的麻烦在于它还将包含值 >= 1000 的逗号分隔符。)


性能

这种方法将通过 table 单次传递,比其他解决方案更有效,这些解决方案会增加具体化内联视图(派生的 tables)的额外开销。