如何对 group by 的百分比计算进行分组

How to group percentage calculations on group by

我有以下 table 数据:

我的table(国家、性别):

+----------+----------+
| country  | gender   |
+----------+----------+
| China    | male     |
+----------+----------+
| China    | female   |
+----------+----------+
| China    | male     |
+----------+----------+
| China    | male     |
+----------+----------+
| Russia   | male     |
+----------+----------+
| Russia   | female   |
+----------+----------+

我想要这样的查询 select 输出:

+----------+----------+--------+-----------+
| country  | gender   | count  | percent   |
+----------+----------+--------+-----------+
| China    | male     |   3    |     75    |
+----------+----------+--------+-----------+
| China    | female   |   1    |     25    |
+----------+----------+--------+-----------+
| Russia   | male     |   1    |    50     |
+----------+----------+--------+-----------+
| Russia   | female   |   1    |    50     |
+----------+----------+--------+-----------+

所以基本上我想计算每个国家/地区的性别百分比。

我该怎么做?

非常感谢

Sql Fiddle Demo

SELECT g.country, 
        g.gender, 
        g.gender_count, 
        (g.gender_count * 1.0 / c.country_count) * 100
 FROM (
        SELECT country, gender, count(*) as gender_count
        FROM YourTable
        GROUP BY country, gender
      ) g
 JOIN (
        SELECT country, count(*) as country_count
        FROM YourTable
        GROUP BY country
      ) c
   ON g.country = c.country

你可以试试这个.. (在 Oracle 11 上测试):

  with w_data as (
        select 'China' country, 'male'  gender from dual union all
        select 'China'        , 'female'       from dual union all
        select 'China'        , 'male'         from dual union all
        select 'China'        , 'male'         from dual union all
        select 'Russia'       , 'male'         from dual union all
        select 'Russia'       , 'female'       from dual 
        ),
     w_sub as (
        select country, gender, count(*) ccount
          from w_data
         group by country, gender
        )
  select country, gender, ccount,
         ratio_to_report(ccount) over (partition by country)*100 percent
    from w_sub
  order by country, ccount desc
  /

  COUNTR GENDER     CCOUNT    PERCENT
  ------ ------ ---------- ----------
  China  male            3         75
  China  female          1         25
  Russia female          1         50
  Russia male            1         50

避免使用 "WITH" 子句(因为我认为这不适用于某些数据库)...假设 RATIO_TO_REPORT 有效... 相同的查询略有不同:

  select country, gender, ccount,
         ratio_to_report(ccount) over (partition by country)*100 percent
    from (
           select country, gender, count(*) ccount
             from (
                    select 'China' country, 'male'  gender from dual union all
                    select 'China'        , 'female'       from dual union all
                    select 'China'        , 'male'         from dual union all
                    select 'China'        , 'male'         from dual union all
                    select 'Russia'       , 'male'         from dual union all
                    select 'Russia'       , 'female'       from dual 
                    )  w_data
            group by country, gender
           )
  order by country, ccount desc
  /

最后,如果没有,请避免 RATIO_TO_REPORT:

  select country, gender, ccount,
         (ccount / SUM(ccount) over (partition by country))*100 percent
    from (
           select country, gender, count(*) ccount
             from (
                    select 'China' country, 'male'  gender from dual union all
                    select 'China'        , 'female'       from dual union all
                    select 'China'        , 'male'         from dual union all
                    select 'China'        , 'male'         from dual union all
                    select 'Russia'       , 'male'         from dual union all
                    select 'Russia'       , 'female'       from dual 
                    )  w_data
            group by country, gender
           )
  order by country, ccount desc
  /

你可以这样使用:

select a.country, 
       a.gender, 
       (count(*) / b.qtd)*100 as percent
  from test a inner join
       (select country, count(*) qtd from test group by country) b
      on a.country = b.country
 group by a.country, a.gender

不需要两个子查询! 在这里查看:http://sqlfiddle.com/#!9/f41609/4

只需在主查询中对国家和性别进行分组,然后在子查询中获取每个组中有多少性别,应用百分比公式。

select 
  a.country, 
  a.gender,
  count(a.gender) as `count`, 
  (
    select count(a.gender) / count(gender) * 100 
    from mytable 
    where country = a.country
  ) as percent
from mytable a 
group by 
  a.country, 
  a.gender
order by
  country,
  gender desc,
  percent desc