SQL查询在负数中运行总计

时间:2016-05-05 17:42:36

标签: sql sql-server

我有一张负面进展表

Id  ActivityID  Date   progress
1   x           Jan-10 10
2   y           Jan-10 20
3   x           Feb-10 30
4   y           Feb-10 -5
5   x           Mar-10 -10
6   y           Mar-10 25
7   x           Apr-10 30
8   y           Apr-10 20
9   x           May-10 40
10  y           May-10 40

我的目的是获得累积而没有我做过的否定:

select t1.id,t1.ActivityID,t1.Date,t1.progress,SUM(t2.progress) as sum
from tblIncrement t1
inner join tblIncrement t2
on cast('1.' + t1.date as datetime) >= cast('1.' + t2.date as datetime) and 
t1.ActivityID = t2.ActivityID
where t1.Progress > 0
group by t1.id,t1.activityID,t1.Date,t1.progress
order by t1.ActivityID,cast('1.' + t1.date as datetime)

结果:

id  ActivityID  Date   progress sum
1   x           Jan-10 10       10
3   x           Feb-10 30       40
7   x           Apr-10 30       60
9   x           May-10 40       100
2   y           Jan-10 20       20
6   y           Mar-10 25       40
8   y           Apr-10 20       60
10  y           May-10 40       100

我的最后一项任务是从该总和中获得周期性进展:

预期结果:

id  ActivityID  Date   progress sum Periodic
1   x           Jan-10 10       10  10
3   x           Feb-10 30       40  30
7   x           Apr-10 30       60  20
9   x           May-10 40       100 40
2   y           Jan-10 20       20  20
6   y           Mar-10 25       40  20
8   y           Apr-10 20       60  20
10  y           May-10 40       100 40

2 个答案:

答案 0 :(得分:2)

大多数数据库都支持ANSI标准窗口函数,包括累积和。这简单易行:

select i.*,
       sum(progress) over (partition by activityid order by date) as sumeprogress
from tblIncrement i
where i.progress > 0;

我不确定"定期进展"是。

答案 1 :(得分:1)

所以:

select t1.id,t1.ActivityID,t1.Date,t1.progress
, SUM(CASE WHEN t1.progress > 0 THEN t2.progress ELSE 0 END) as sum
, SUM(t2.progress) as Periodic
from tblIncrement t1
inner join tblIncrement t2
on cast('1.' + t1.date as datetime) >= cast('1.' + t2.date as datetime) and 
t1.ActivityID = t2.ActivityID
group by t1.id,t1.activityID,t1.Date,t1.progress
order by t1.ActivityID,cast('1.' + t1.date as datetime)

为你做这份工作?

编辑:

  

......但我的意图是得到   来自" Sum"排除负面记录后列出进度。   因此,基本上重新生成累积的进度 - 奥马尔Shahine   oshahine 5分钟前

这是我的最终答案:

SELECT t.Id, t.ActivityID, t.Date, t.progress, t.sumprogress 
, t.sumprogress - CASE WHEN (Lag(t.ActivityID) OVER (ORDER BY t.ActivityID, t.ID)) = t.ActivityID THEN Coalesce(Lag(t.sumprogress) OVER (ORDER BY t.ActivityID, t.ID), 0) ELSE 0 END AS Periodic
FROM 
( 
   SELECT i.Id, i.ActivityID, i.Date, i.progress
   , Sum(progress) OVER (PARTITION BY activityid ORDER BY cast('1.' + i.date as DateTime)) as sumprogress 
   FROM tblIncrement i
) AS t 
WHERE Progress > 0 
ORDER BY ActivityID, cast('1.' + t.date as DateTime) 

我用你的测试数据对它进行了测试,似乎做得很好。