如何在SQL Server中维护每个用户的累积总和

时间:2014-05-28 10:14:35

标签: sql sql-server

我有一张像

这样的表
ID UserID     rupees  time 

1    1       200   2014-01-05
---------------------------------
2    1     500    2014-04-06
----------------------------------
3    2      10     2014-05-05
----------------------------------
4    2      20     2014-05-06
----------------------------------

我想输出谎言

ID    UserID  Rupees    time         CumulativeSum

1      1       200   2014-01-05       200
-------------------------------------------------
2      1       500   2014-04-06       700
-------------------------------------------------
3      2        10    2014-05-06        10
-------------------------------------------------
4      2        20    2014-05-06        30
---------------------------------------------------

如何将此表作为purput

6 个答案:

答案 0 :(得分:1)

请尝试使用CTE

;With T as(
select 
    *, 
    ROW_NUMBER() over(partition by UserId order by [time]) RN
from tbl
)
select 
    UserID, 
    rupees, 
    [time],
    (select SUM(rupees) 
    from T b 
    where b.UserID=a.UserID and b.RN<=a.RN) CumulativeSum
from T a

对于列值时间增加的记录,请尝试以下查询:

select 
    UserID, 
    rupees, 
    [time],
    (select SUM(rupees) 
    from tbl b 
    where b.UserID=a.UserID and b.[time]<=a.[time]) CumulativeSum
from tbl a

答案 1 :(得分:1)

对于SQL Server 2012或更高版本,您可以将SUM()OVER clause一起使用,以指定ROW子句:

declare @t table (ID int,UserID int,rupees int,[time] date)
insert into @t(ID,UserID,rupees,[time]) values
(1,1,200,'20140105'),
(2,1,500,'20140406'),
(3,2, 10,'20140505'),
(4,2, 20,'20140506')

select
    *,
    SUM(rupees) OVER (
        PARTITION BY UserID
        ORDER BY id /* or time? */
        ROWS BETWEEN
            UNBOUNDED PRECEDING AND
            CURRENT ROW)
    as total
from @t

结果:

ID          UserID      rupees      time       total
----------- ----------- ----------- ---------- -----------
1           1           200         2014-01-05 200
2           1           500         2014-04-06 700
3           2           10          2014-05-05 10
4           2           20          2014-05-06 30

答案 2 :(得分:1)

        DECLARE @t table (UserID INT,rupees INT,DateKey Date )
        INSERT INTO @t VALUES 
    (1,200,'2014-01-05'),
        (2,300,'2014-01-06'),
        (2,800,'2014-03-06')
        select UserID,
                rupees,
                DateKey,
        (SELECT SUM(rupees)from @t t 
        where t.rupees <= tt.rupees)  from  @t tt
        GROUP BY UserID,rupees,DateKey

答案 3 :(得分:0)

希望这对你有所帮助。

DECLARE @tab TABLE (id INT,userId INT,rupees INT,[time] Date)
INSERT INTO @tab VALUES
(1,1,200 ,'2014-01-05'),
(2,1,500 ,'2014-04-06'),
(3,2,10  ,'2014-05-05'),
(4,2,20  ,'2014-05-06')

SELECT  LU.id,LU.userId,LU.rupees,LU.time,SUM(b.rupees) CumulativeSum
FROM    (SELECT *,ROW_NUMBER() OVER (PARTITION BY userId ORDER BY [time]) R FROM @tab) B
JOIN    (SELECT *,ROW_NUMBER() OVER (PARTITION BY userId ORDER BY [time]) R FROM @tab) LU
ON      B.userId = LU.userId AND B.R <= LU.R
GROUP BY LU.id,LU.userId,LU.rupees,LU.time

<强>结果

enter image description here

答案 4 :(得分:0)

我假设您没有使用SQL Server 2012,它提供累积和函数。其他答案使用某种形式的row_number()函数,但这些似乎完全没必要。我通常使用相关子查询来处理累积和:

select ID, UserID, rupees, [time],
       (select sum(rupees)
        from table t2
        where t2.UserId = t.UserId and
              t2.ID <= t.ID
       ) as CumulativeSum
from table t;

这需要一个唯一标识每一行的列,这似乎是id的目的。为了提高性能,我希望在table(UserId, ID, rupees)上建立一个索引。

答案 5 :(得分:-1)

enter image description here

select *,  SUM(rupees)  OVER (
    PARTITION BY UserID
    ORDER BY id) as CumSum from #tbl