分组,将行转换为没有聚合的列

时间:2014-12-17 16:15:36

标签: mysql sql nhibernate

我需要在查询期间对表进行分组,直到知道我在查询后这样做 - 使用代码作为我的组非常复杂。但是对于新数据,它似乎需要几分钟,而我认为有更好的方法。

我当前的查询结果如下:

FKId | Name | A | B | C
 1     Alpha  2   3   2
 1     Beta   2   5   7
 2     Alpha  8   1   10
 2     Beta   7   -5   6
 2     Gamma  1   2   3

我将其转换为:

FKId | Alpha[A] | Alpha[B] | Alpha[C] | Beta[A] | Beta[B] | Beta[C] | Gamma[A] | Gamma[B] | Gamma[C]
 1      2           3          2          2          5        7
 2      8           1          10         7         -5        6         1          2           3

是否可以使用SQL? (我认为它应该比使用代码执行此操作要快得多)

  • 名字可以是任何
  • 我有很多支柱A,B,C(如20 - 30)。结果列的数量很容易达到数千,因为平均项目有大约100个名称。
  • 我有10-20列我应该分组,但是由FKId做一个组很好 - 这些列都是一样的。
  • 我们使用不同的SQL DB,因此我无法使用PIVOT等特定功能。我知道我们经常使用MySQL,MsSQL和SQLite
  • 我们使用NHibernate,如果它有任何区别。
  • 如果使用特定功能,我也会尊重为MySQL所做的解决方案。我们以80%的比例使用它,如果我能够至少为MySQL做到这一点,它将大大提高平均性能。

1 个答案:

答案 0 :(得分:0)

基本上,您想要转置数据。这是你可以尝试的。它应该适用于所有数据库,但您需要事先知道列A,B,C等:

create table my_table (
  fkid integer,
  name varchar(10),
  a integer,
  b integer,
  c integer
);

insert into my_table values(1,'alpha',2,3,2)
,(1,'beta',2,5,7)
,(2,'alpha',8,1,10)
,(2,'beta',7,-5,6)
,(2,'gamma',1,2,3);


select fkid
, max(case when name = 'alpha' then a else null end) as alphaa
, max(case when name = 'alpha' then b else null end) as alphab
, max(case when name = 'alpha' then c else null end) as alphac
, max(case when name = 'beta' then a else null end) as betaa
, max(case when name = 'beta' then b else null end) as betab
, max(case when name = 'beta' then c else null end) as betac
, max(case when name = 'gamma' then a else null end) as gammaa
, max(case when name = 'gamma' then b else null end) as gammab
, max(case when name = 'gamma' then c else null end) as gammac
from my_table
group by fkid;