选择每个GROUP BY组的平均值?

时间:2014-06-28 19:34:28

标签: sql oracle count group-by aggregate-functions

=====编辑:修改原始问题=====

根据评论,我编辑了原始问题(我最后留下原来的问题)如下:

我有一个样本员工数据存储在表格(emp)中,如下所示:

ID   | Key | Value
1000 |  1  | Engineer
1000 |  2  | Male
1000 |  3  | 30
1001 |  1  | Manager
1001 |  2  | Female
1001 |  3  | 35

其中键映射到另一个表(key_prop):

Key | Value
1   | Type
2   | Sex
3   | Age
4   | ID

我正在寻找按员工类型分组的员工统计数据:

Type      | Count | Number of Males | Number of Females | Avg Age 
Engineers |       |                 |                   |
Managers  |       |                 |                   |

很容易获得第一列(我正在使用Oracle SQL):

SELECT (key_prop.value, COUNT(key_prop.value))
FROM 
  emp 
INNER JOIN
  key_prop
ON
  key_prop.id = emp.id
AND
  key_prop.value = 1
GROUP BY key_prop.value

但我似乎无法在同一查询中获取其他列。我是否必须将多个内部联接组合在一起或使用嵌套的SQL查询?

==下面的原始帖子==

我将样本员工数据存储为KVP行,如下所示:

Type | Engineer
Sex  | Male
Age  | 30
Type | Manager
Sex  | Female
Age  | 35
...

我正在寻找按员工类型分组的员工统计数据:

Type      | Count | Number of Males | Number of Females | Avg Age 
Engineers |       |                 |                   |
Managers  |       |                 |                   |

很容易获得第一列(我正在使用Oracle SQL)。但我似乎无法在同一个查询中获取其他列。

4 个答案:

答案 0 :(得分:1)

您应按类型分组,然后使用具有准确条件的聚合函数:

SELECT 
    type,
    COUNT(*) AS count,
    COUNT(CASE WHEN Sex = 'Male' THEN 1 ELSE NULL END) AS number_of_males,
    COUNT(CASE WHEN Sex = 'Female' THEN 1 ELSE NULL END) AS number_of_females,
    AVG(age) AS avg_age
FROM employees
GROUP BY type

答案 1 :(得分:1)

您可以先按员工ID聚合然后重新聚合:

select type,
       count(*) as num,
       sum(case when sex = 'male' then 1 else 0 end) as males,
       sum(case when sex = 'female' then 1 else 0 end) as females,
       avg(cast(age as decimal(5, 2))) as avgage
from (select employeeid,
             max(case when col1 = 'type' then value end) as type,
             max(case when col1 = 'sex' then value end) as sex,
             max(case when col1 = 'age' then value end) as age
      form employees e
      group by employeeid
     ) t
group by type;

答案 2 :(得分:0)

这是在MySQL工作......

让我们建立数据库:

mysql> create database test;
Query OK, 1 row affected (0.00 sec)

mysql> use test;
Database changed

mysql> create table e(name VARCHAR(10), type VARCHAR(10), sex VARCHAR(10));
Query OK, 0 rows affected (0.01 sec)

mysql> insert into e set name='john', type='barvaz', sex='M';
Query OK, 1 row affected (0.01 sec)

mysql> insert into e set name='miko', type='barvaz', sex='M';
Query OK, 1 row affected (0.01 sec)

mysql> insert into e set name='mako', type='barvaz', sex='M';
Query OK, 1 row affected (0.01 sec)

mysql> insert into e set name='mona', type='barvaz', sex='F';
Query OK, 1 row affected (0.01 sec)

现在只是一个示例:

mysql> select *,IF(sex='M', 1, 0) AS sex FROM e;
+-------+--------+------+-----+
| name  | type   | sex  | sex |
+-------+--------+------+-----+
| john  | barvaz | M    |   1 |
| miko  | barvaz | M    |   1 |
| mako  | barvaz | M    |   1 |
| mona  | barvaz | Y    |   0 |
+-------+--------+------+-----+
4 rows in set (0.00 sec)

执行查询:

mysql> select *,SUM(IF(sex='M', 1, 0)) AS sex FROM e;
+-------+--------+------+------+
| name  | type   | sex  | sex  |
+-------+--------+------+------+
| john  | barvaz | M    |    3 |
+-------+--------+------+------+
1 row in set (0.01 sec)

我们在寻找什么:

mysql> select type,sex,SUM(IF(sex='M', 1, 0)) as Males, SUM(IF(sex='F', 1, 0)) AS Females FROM e;
+--------+--------+-------+---------+
| type   | sex    | Males | Females |
+--------+--------+-------+---------+
| barvaz | M      |     3 |       1 |
+--------+--------+-------+---------+

1 row in set (0.00 sec)

当然,您可以根据需要添加一些GROUP BY。

答案 3 :(得分:-2)

我不是Oracle SQL专家。但我确实知道MySQL和ASIC SQL非常好。通常在这种情况下我使用IF和SUM。

因此:

SELECT
  SUM(IF(Sex='Male', 1, 0)) AS number_of_males,
  SUM(IF(Sex='Feamle', 1, 0)) AS number_of_females,
  AVG(age) AS avg_age
FROM
 Employees
WHERE
 type='Engineer';

希望它有所帮助。