如何在 T-SQL 中将列与旋转其他列相加

Posted

技术标签:

【中文标题】如何在 T-SQL 中将列与旋转其他列相加【英文标题】:How to sum column with pivoting other column in T-SQL 【发布时间】:2021-11-27 21:04:17 【问题描述】:

在下面的示例中,您如何总结“费用”列并制作唯一的 ControlNo?

代码示例:

IF OBJECT_ID('tempdb..#table1') IS NOT NULL 
    DROP TABLE #table1

CREATE TABLE #Table1 
(
     ControlNo INT, 
     Line varchar(50), 
     Profit INT, 
     Fee INT
)

INSERT INTO #Table1 (ControlNo, Line, Profit, Fee) 
VALUES (1111, 'Line1', 80, 30), 
       (1111, 'Line2', 100, 20), 
       (3333, 'Line1', 200, 50), 
       (4444, 'Line1', 50, 10), 
       (4444, 'Line2', 100, 40)

-- check
--select * from #Table1

SELECT * 
FROM #Table1
PIVOT
    (SUM(Profit)
        FOR Line IN ([Line1], [Line2])
    ) pvt
ORDER BY ControlNo

输出如下所示:

但需要看起来像这样:

ControlNo   Fee Line1   Line2
1111        50  80      100
3333        50  200     0
4444        50  50      100

更新:

遵循戴尔的解决方案

我尽可能地模仿真实数据,但由于某种原因,81 的 TerrPrem 正在消失?

IF OBJECT_ID('tempdb..#table1') IS NOT NULL DROP TABLE #table1

Create table #Table1 ( Guid uniqueidentifier, ControlNo int, Line varchar(50), Prem INT, TerrPrem int )

INSERT INTO #Table1 (Guid, ControlNo, Line, Prem, TerrPrem) 
    VALUES  ('169E54D8-F00A-43B8-9268-5DD3F5684C5A',4395768, 'Commercial General Liability',10987,0), 
            ('169E54D8-F00A-43B8-9268-5DD3F5684C5A',4395768, 'Commercial General Liability',81,81), 
            ('169E54D8-F00A-43B8-9268-5DD3F5684C5A',4395768, 'Contractors Pollution Liability',1013,0), 
            ('169E54D8-F00A-43B8-9268-5DD3F5684C5A',4395768, 'Contractors Pollution Liability',81,81)

-- check
--select * from #Table1



select * 
from #Table1
PIVOT(
SUM(Prem)
FOR Line IN ([Commercial General Liability],             
             [Contractors Pollution Liability])
             ) as PivotTable

为什么其中一个 TerrPrem 消失了?

                Guid                    ControlNo   TerrPrem    Commercial General Liability    Contractors Pollution Liability
169E54D8-F00A-43B8-9268-5DD3F5684C5A    4395768         0                   10987                           1013
169E54D8-F00A-43B8-9268-5DD3F5684C5A    4395768         81                    81                            81

【问题讨论】:

根据问题指南,请不要发布代码、数据、错误消息等的图像 - 将文本复制或输入到问题中。请保留将图像用于图表或演示渲染错误,无法通过文本准确描述的事情。 正如我已经评论过的,请停止使用图像作为数据,尤其是异地图像。只需将数据格式化为代码或表格文本。 您希望从新数据中得到什么结果? 我预计 TerrPrem 的总价为 162 美元。 81+81之和 你也没有向我们展示你正在使用的实际代码...... 【参考方案1】:

对于只有 2 种线型,最好使用 case 表达式

select [Guid], ControlNo, TerrPrem * count(*)
  , sum(case when Line = 'Commercial General Liability' then Prem else 0 end) [Commercial General Liability]
  , sum(case when Line = 'Contractors Pollution Liability' then Prem else 0 end) [Contractors Pollution Liability]
from #table1
group by [Guid], ControlNo, TerrPrem
order by [Guid], ControlNo, TerrPrem;

【讨论】:

谢谢戴尔。我尽可能地模仿读取数据,但由于某种原因 TerrPrem 列没有总结。我更新了问题。 请尝试我的新答案。 谢谢。这个可行,但我只是想了解为什么更新的示例没有总结出来。我错过了什么? @user17101118 如果您查看您的支点,它会在Line 上进行支点,并且您只有两个不同的Line 值,并且它不允许您聚合多个值,因此您可以t 计算有多少行被归为一组。 感谢您的宝贵时间!【参考方案2】:

只是另一种选择...通过CROSS APPLY 展开行并将[Fee] 添加到PIVOT

Select ControlNo
      ,Fee   = IsNull(Fee,0)
      ,Line1 = IsNull(Line1,0)
      ,Line2 = IsNull(Line2,0)
 From (
        select ControlNo 
              ,B.*
         From #Table1 A
         Cross Apply ( values ('Fee',Fee)
                             ,(Line,Profit)
                     ) B(Item,Value)
      ) src
 Pivot ( sum(Value) for Item in ([Fee],[Line1],[Line2] ) ) pvt

结果

OR...您可以使用条件聚合

Select ControlNo
      ,Fee   = sum(Fee)
      ,Line1 = sum( case when Line='Line1' then Profit else 0 end)
      ,Line2 = sum( case when Line='Line2' then Profit else 0 end)
 From  #Table1
 Group By ControlNo

【讨论】:

这太棒了!谢谢

以上是关于如何在 T-SQL 中将列与旋转其他列相加的主要内容,如果未能解决你的问题,请参考以下文章

如何在休眠中将表列与另一个表列映射

如何将一个熊猫数据框的一列与另一个数据框的每一列相加?

在 Python 中将数据框列与可接受的偏差进行比较

在vba中将列与文本框值相乘

T-SQL行合并成列与列拆分成行

T-SQL行合并成列与列拆分成行