SQL累计%总计

时间:2012-08-28 13:52:39

标签: sql sql-server-2008 running-total

我的数据集如下所示:

COLA  | COLB
Name1 | 218
Name2 | 157
Name3 | 134
Name4 | 121

我需要这个输出:

COLA  | COLB| COLC
Name1 | 218 | 0.34
Name2 | 157 | 0.60
Name3 | 134 | 0.71
Name4 | 121 | 1

到目前为止,我的SQL看起来像这样:

SELECT COLA, COLB, COLB/SUM(COLB) FROM #MyTempTable

此SQL存在两个问题。一,COLC每次都是0,我不明白。二,即使它确实导致%它不是累积%。

我在StackOverflow上看到了一些类似的线程,但是我无法在这些线程中找到答案。

提前感谢任何建议!

3 个答案:

答案 0 :(得分:4)

我认为你正在寻找类似的东西,尽管你的例子计算可能有些偏差:

SELECT
    COLA,
    COLB,
    ROUND(
        -- Divide the running total...
        (SELECT CAST(SUM(COLB) AS FLOAT) FROM #MyTempTable WHERE COLA <= a.COLA) /
        -- ...by the full total
        (SELECT CAST(SUM(COLB) AS FLOAT) FROM #MyTempTable),
        2
    ) AS COLC
FROM #MyTempTable AS a
ORDER BY COLA
编辑:我添加了四舍五入。

这给了我们以下输出:

COLA    COLB    COLC
Name1   218     0.35
Name2   157     0.6
Name3   134     0.81
Name4   121     1

结果为0(或1)的原因是因为你用整数划分整数,因此给你一个int(见Datatype precedence)。

更新:

我应该补充说,这会使用“triangular join”来获取总计(WHERE COLA <= a.COLA)。如果性能成为问题,您可以将其与other options进行比较,具体取决于您的SQL Server版本。

答案 1 :(得分:1)

如果您不使用OLAP函数,那么您必须在表上进行奇怪的自联接:

SELECT a.ColA, a.ColB, SUM(b.ColB) AS ColX
  FROM #MyTempTable AS a
  JOIN #MyTempTable AS b
    ON a.ColA <= b.ColA
 GROUP BY a.ColA, a.ColB

这为您提供原始累积SUM。您绝对可以使用它作为子查询来获得答案,并指出要获得百分比,您需要将累计总和除以总和:

SELECT ColA, ColB, ColX / (SELECT SUM(ColB) FROM MyTempTable) AS ColC
  FROM (SELECT a.ColA, a.ColB, SUM(b.ColB) AS ColX
          FROM #MyTempTable AS a
          JOIN #MyTempTable AS b
            ON a.ColA <= b.ColA
         GROUP BY a.ColA, a.ColB
       ) AS X
 ORDER BY ColA

您可能只能写:

SELECT a.ColA, a.ColB, SUM(b.ColB) / (SELECT SUM(ColB) FROM MyTempTable) AS ColC
  FROM #MyTempTable AS a
  JOIN #MyTempTable AS b
    ON a.ColA <= b.ColA
 GROUP BY a.ColA, a.ColB
 ORDER BY a.ColA

将ColC表达式乘以100得到百分比而不是分数。

在Mac OS X 10.7.3上对IBM Informix 11.70.FC2进行了测试,两个查询都有分工,产生了相同的答案(我注意到问题中我需要0.81而不是0.71):

Name1    218    0.34603174603174603174603174603175
Name2    157    0.5952380952380952380952380952381
Name3    134    0.80793650793650793650793650793651
Name4    121    1.0 

您可能必须使用CAST来确保使用浮点而不是整数运算来完成除法 - 正如您所看到的那样,Informix不需要(无论如何,SUM是一个浮点小数,以防万一table中有数十亿行,而不仅仅是其中的4行。我可以使用ROUND(xxxx, 2)改进演示文稿,只获得2位小数;对DECIMAL(6,2)的强制转换会达到相同的结果,但是客户端应该负责演示,而不是DBMS。

答案 2 :(得分:0)

在MS SQL Server中,这样做(up,错误的subaggregation - &gt;错误的结果):

create table #MyTempTable (cola varchar(10), colb int)

insert into #MyTempTable(cola,colb)
select 'Name1',218
union all
select 'Name2',157
union all
select 'Name3',134
union all
select 'Name4',121

SELECT otab.COLA, otab.COLB,
       cast(otab.COLB as float)/(select SUM(cast(itab.colb as float))
                                 from #MyTempTable itab where itab.cola >= otab.cola) 
  from #MyTempTable otab

drop table #MyTempTable