按行值分组的列总和

Posted

技术标签:

【中文标题】按行值分组的列总和【英文标题】:Sum of columns grouped by its row value 【发布时间】:2013-05-15 17:54:16 【问题描述】:

我想创建查询来总结 Table1 如下:

Table1:
+-----+------+-----+------+
|Col1 | Col2 |Col3 | Col4 |
|1    | 2    |3    |  1   |
|3    | 2    |1    |  1   |
|2    | 1    |3    |  1   |
+-----+------+-----+------+
Output:   
 +----+---+-----+-----+----+----+                    
 |    | 1 |  2  |  3  |  4 |  5 |    
 +----+---+-----+-----+----+----+
 |Col1| 1 |  2  |  3  |    |    |      
 |Col2| 1 |  4  |     |    |    |       
 |Col3| 1 |     |  6  |    |    |     
 |Col4| 3 |     |     |    |    |
 +----+---+-----+-----+----+----+                                     

我最好的方法是使用 TRANSFORM PIVOT。

【问题讨论】:

请发表您对 SQL 的最佳尝试。 @Randy,感谢您的回复。我发布了我的最佳尝试。我的计划是使 TRANSFORM PIVOT 脱离此查询,因为我无法在一个查询中进行。 编辑您的问题以包含您的最大努力 【参考方案1】:

您需要先使用 UNION ALL 对数据进行 UNPIVOT,然后再应用 PIVOT/TRANSFORM:

transform sum(val)
select col
from
(
  SELECT 'Col1' as col, Col1 as Val
  FROM test
  union all
  SELECT 'Col2' as col, Col2 as Val
  FROM test
  union all
  SELECT 'Col3' as col, Col3 as Val
  FROM test
  union all
  SELECT 'Col4' as col, Col4 as Val
  FROM test
) src
group by col
pivot val;

UNION ALL 查询将多列 col1col2 等转换为单列中的多行,然后您可以应用 TRANSFORM 函数。

注意:此查询已在 MS Access 2010 中测试并返回结果:

+------+---+---+---+
| col  | 1 | 2 | 3 |
+------+---+---+---+
| Col1 | 1 | 2 | 3 |
| Col2 | 1 | 4 |   |
| Col3 | 1 |   | 6 |
| Col4 | 3 |   |   |
+------+---+---+---+

编辑,根据您的评论,您需要所有值都出现1-5,然后我建议使用这些小改动。

首先,创建一个包含您想要显示的所有数字的表格:

create table numbers
(
  n number
);

insert into numbers values (1);
insert into numbers values (2);
insert into numbers values (3);
insert into numbers values (4);
insert into numbers values (5);

一旦您有了一个包含所有要显示的值的表,然后使用上面的 UNION ALL 查询创建一个单独的查询。下面的查询是我创建并保存的,名称为unpiv,但你可以随便叫它:

SELECT 'Col1' as col, Col1 as Val 
FROM test
union all
SELECT 'Col2' as col, Col2 as Val
FROM test
union all
SELECT 'Col3' as col, Col3 as Val
FROM test
UNION ALL SELECT 'Col4' as col, Col4 as Val
FROM test;

获得结果的关键是为每一列创建一个包含所有数字的列表,因此您将使用如下内容:

SELECT col, val
from numbers, (select distinct col from unpiv);

这会生成每个列名称的笛卡尔结果,其中包含您要显示的数字。最后,您将上述查询加入到您的unpiv 查询中,以便您可以转换数据。最后的查询是:

transform sum(u.val)
select src.col
from
(
  SELECT col, val
  from numbers, (select distinct col from unpiv)
) src
left join unpiv u
  on src.col = u.col
  and src.val = u.val
group by src.col
pivot src.val;

在 MS Access 2010 中测试给出了结果:

+------+---+---+---+---+---+
| col  | 1 | 2 | 3 | 4 | 5 |
+------+---+---+---+---+---+
| Col1 | 1 | 2 | 3 |   |   |
| Col2 | 1 | 4 |   |   |   |
| Col3 | 1 |   | 6 |   |   |
| Col4 | 3 |   |   |   |   |
+------+---+---+---+---+---+

【讨论】:

谢谢蓝脚。您回答正确,但我还需要显示第 4 列和第 5 列,无论它们有值还是根本没有值。

以上是关于按行值分组的列总和的主要内容,如果未能解决你的问题,请参考以下文章

熊猫将行值除以聚合总和,条件由其他单元格设置

按行的出现分组

对唯一行值进行分组 Postgis、postgres 和 Qgis

将行值转换为火花数据框中的列数组

在同一分组中添加具有上述所有行总和的列

Oracle SQL 行到具有分组依据和总和的列