Sql 按组选择每组的平均值?

Sql 按组选择每组的平均值?,sql,oracle,count,group-by,aggregate-functions,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 Type | Engineer Sex | Male Age | 30 Type | M

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

根据评论,我将原始问题(我将原始问题保留在末尾)编辑如下:

我将样本员工数据存储在如下表(emp)中:

ID   | Key | Value
1000 |  1  | Engineer
1000 |  2  | Male
1000 |  3  | 30
1001 |  1  | Manager
1001 |  2  | Female
1001 |  3  | 35
Type | Engineer
Sex  | Male
Age  | 30
Type | Manager
Sex  | Female
Age  | 35
...
其中键映射到另一个表中(键属性):

我正在查找按员工类型分组的员工统计信息:

Type      | Count | Number of Males | Number of Females | Avg Age 
Engineers |       |                 |                   |
Managers  |       |                 |                   |
Type      | Count | Number of Males | Number of Females | Avg Age 
Engineers |       |                 |                   |
Managers  |       |                 |                   |
很容易获得第一列(我使用的是Oracle SQL):

但我似乎无法在同一个查询中获得其他列。我必须将几个内部联接分组在一起还是使用嵌套的SQL查询

==以下原始过账==

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

ID   | Key | Value
1000 |  1  | Engineer
1000 |  2  | Male
1000 |  3  | 30
1001 |  1  | Manager
1001 |  2  | Female
1001 |  3  | 35
Type | Engineer
Sex  | Male
Age  | 30
Type | Manager
Sex  | Female
Age  | 35
...
我正在查找按员工类型分组的员工统计信息:

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

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

我不是Orcale 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';

希望能有所帮助。

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

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

您可以先按员工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;

在这里,它在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)

当然,您可以根据需要添加一些分组。

行之间是如何连接的?SQL表天生就是无序的。是的,这是正确的。我可能过于简化了这个例子,这样问题就更容易理解了。实际上,有另一个KVP来存储每个员工的iD,第一列实际上是另一个表的一部分。“过于简单化”是对更了解的人的侮辱(例如@Gordon Linoff)。请不要过于简单化。请编辑您的问题,让我们清楚地了解关键值的来源。我为造成的混淆道歉;这是我第一次发帖。我已编辑了原始问题。再次感谢您的帮助。这既不是有效的标准SQL,也不是有效的Oracle SQL。我不知道您为什么写这篇文章或投票否决我。。。既然你自己没试过。。。请看下面我的第二个答案!您是否看到
oracle
标签?SQL根本不适用于Oracle(因为在中没有
),您知道Oracle和MySQL有不同的语法吗?上述内容不适用于Oracle(或任何其他符合标准的DBMS)。一个原因是Oracle(或一般的SQL)没有
IF
语句,但更重要的是,您使用的
group by
也是无效的SQL,除了MySQL之外,在任何其他DBMS中都无法工作