跨列和行求和

Posted

技术标签:

【中文标题】跨列和行求和【英文标题】:Sum across columns and rows 【发布时间】:2015-02-27 08:35:12 【问题描述】:

考虑这样的表格

table
+--------+---------+-----------+---------+-----------+
| BookId | ItemId1 | Quantity1 | ItemId2 | Quantity2 |
+--------+---------+-----------+---------+-----------+
|      1 |       1 |         2 |       2 |         1 |
|      1 |       3 |         1 |       2 |         1 |
|      2 |       1 |         1 |       2 |         1 |
+--------+---------+-----------+---------+-----------+

现在我想获取按书籍分组的每个项目的列数量总和。那么我怎样才能在不同的列中求和呢?现在我使用一种尴尬的解决方案,比如构建一个临时表,然后查询这个,但它必须以更优雅的方式实现!?

select
    BookId 'BookId',
    ItemId1 'ItemId',
    Quantity1 'Quantity'
into #temptab
from table
union all
select
    BookId,
    ItemId2,
    Quantity2
from table

然后

select 
    BookId,
    ItemId,
    sum(Quantity)
from #temptab
group by ItemId, BookId

我怎样才能摆脱这个中间步骤?

期望的输出:

+--------+--------+----------+
| BookId | ItemId | Quantity |
+--------+--------+----------+
|      1 |      1 |        2 |
|      1 |      3 |        1 |
|      1 |      2 |        2 |
|      2 |      1 |        1 |
|      2 |      2 |        1 |
+--------+--------+----------+

【问题讨论】:

如果 ItemId1 与 ItemId2 匹配,是否要将它们相加? 使用 UNPIVOT 命令。 您应该设计数据模型以反映数据,而不是电子表格或某种物理形式。有重复的列组通常是一个不好的迹象。 ItemId1ItemId2 有什么本质上的不同吗?如果是这样,为什么您现在要针对此查询对它们进行相同的处理?如果没有,为什么表中不只有一个 ItemIdQuantity 列和更多 @ Damien_The_Unbeliever 原则上你是对的。但是,这是我无法更改且没有影响的数据结构 【参考方案1】:

使用cross applytable valued constructorunpivot 数据,然后根据bookiditem 查找sum

这将避免您的中间步骤

SELECT BookId,
       item,
       Sum(quantity)
FROM   Youratble
       CROSS apply (VALUES(Quantity1,ItemId1),
                          (Quantity2,ItemId2))cs(quantity, item)
GROUP  BY BookId,
          item 

正如 Mikael Eriksson 提到的 sql server 2005 使用这个

SELECT BookId,
       item,
       Sum(quantity)
FROM   Youratble
       cross apply 
            (select Quantity1, ItemId1 
             union all 
             select Quantity2, ItemId2) as cs(quantity, item)
GROUP  BY BookId,
          item 

【讨论】:

我搞砸了,把 bookId 放在我的交叉申请中。删除了我的解决方案和 + 1 谢谢。但是,我收到错误“关键字‘值’附近的语法不正确。”似乎表值构造函数仅在 SQL Server 2008 中创建,我使用的是 2005。您也有解决方案吗? @WilliFischer 改为使用 union all cross apply (select Quantity1, ItemId1 union all Quantity2, ItemId2) as cs(quantity, item) @ Mikael Eriksson 但是我再次使用了我想避免的子查询。 @WilliFischer - 已更新。仅供参考,这不是子查询。【参考方案2】:

根据您所做的,您可以使用子查询一步完成:

select 
combined.BookId,
combined.ItemId,
sum(combined.Quantity)
from 
  (select
   BookId 'BookId',
   ItemId1 'ItemId',
   Quantity1 'Quantity'
   from tableName
   union all
   select
   BookId,
   ItemId2,
   Quantity2
   from tableName) as combined
group by combined.ItemId, combined.BookId

【讨论】:

我想避免子查询。还是谢谢

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

excel怎么对一列进行求和

Pandas DataFrame groupby,跨列计数和求和

在 Access CrossTab 查询报告中跨列求和行

python数组求和

excel表格中最后一列怎么自动求和

oracle 行求和