按组查找平均值,然后将列转换为行

iklwldmw  于 2021-07-24  发布在  Java
关注(0)|答案(2)|浏览(289)

我有一张这样的table:

id | q1 | q2 | q3 | type
---+----+----+----+---------
 1 |  1 |  2 |  3 | student
 2 |  2 |  1 |  3 | student
 3 |  1 |  3 |  2 | student
 4 |  3 |  1 |NULL| alumni
 5 |  2 |  1 |NULL| alumni
 6 |  2 |  2 |  1 | student

现在我想要平均groupwise并像这样转换:

q  | Student | Alumni
---+---------+--------    
q1 |   1.5   |  2.5
q2 |   2     |  1
q3 |   2.5   |  NULL
eh57zj3b

eh57zj3b1#

基于c#标记,我假设您使用的是sqlserver。我的建议是使用apply取消数据的IVOT,然后重新聚集:

select v.q,
       avg(case when t.type = 'student' then v.val * 1.0 end) as student,
       avg(case when t.type = 'alumni' then v.val * 1.0 end) as alumni
from tbTest t cross apply
     (values ('q1', t.q1), ('q2', t.q2), ('q3', t.q3)) v(q, val)
group by v.q;

类似的逻辑可以在其他数据库中使用 union all 或者一个明确的 union all .
这是一把小提琴。

l2osamch

l2osamch2#

您想要的操作通常称为 PIVOT 在不同的rdbms中,但它不是标准的sql,也不是每个rdbms都支持的。
如果您没有很多组,那么您可以为每个组硬编码您的查询(就像@dusan建议的那样)

SELECT 
  'q1' as q
  (SELECT AVG(q1) WHERE type='student') as student,
  (SELECT AVG(q1) WHERE type='alumni') as alumni
FROM tbTest
UNION ALL
SELECT 
  'q2'
  (SELECT AVG(q2) WHERE type='student'),
  (SELECT AVG(q2) WHERE type='alumni')
FROM tbTest
UNION ALL
SELECT 
  'q3'
  (SELECT AVG(q3) WHERE type='student'),
  (SELECT AVG(q3) WHERE type='alumni')
FROM tbTest

相关问题