简体   繁体   中英

Get sum of values to the next row in the table

I have a table Parameter_List with fields Parameter_ID,Parameters_Name, Target_Value, GroupID and Sequence_No. The values can be

Parameter_ID    Parameters_Name Target_Value    GroupID Sequence_No  
1   Para_1  1000    2   1  
2   Para_2  2000    2   2  
3   Para_3  3000    2   3  
4   Para_4  NULL    2   4  
5   Para_5  5000    2   5  

6   Para_1  1450    3   1  
7   Para_2  1200    3   2  
8   Para_4  NULL    3   3  
9   Para_5  3000    3   4  

10  Para_2  3000    4   1  
11  Para_3  4000    4   2  
12  Para_4  NULL    4   3  

As you can see, Target_Value for Para_4 is always NULL. Now when I want to display the records, I want the value for Para_4 as the sum of Target_Value of the parameteres above Para_4 for that Group.
For example, for GroupID 2, value of Para_4 should be sum of first 3 rows. Table has a Sequence_No column. So Para_4 should have Target_Value as a sum of all rows above it in that specific group. It should group by GroupID. So the result would look like

Para_1  1000    2
Para_2  2000    2
Para_3  3000    2
Para_4  6000    2
Para_5  5000    2

Para_1  1450    3
Para_2  1200    3
Para_4  2650    3
Para_5  3000    3

One approach is to compute a cumulative sum of the Target_Value in a CTE, then update that CTE wherever the Target_Value be NULL .

WITH cte AS (
    SELECT GroupID, Sequence_No,
        SUM(Target_Value) OVER (PARTITION BY GroupID
            ORDER BY Sequence_No ROWS UNBOUNDED PRECEDING) target_sum
    FROM yourTable
)

UPDATE cte
SET Target_Value = target_sum
WHERE Target_Value IS NULL;
with CTE as (
  select 
     [Parameter_ID],[Parameters_Name],
      (
        select sum(Target_Value) from Parameter_List
        where GroupID = T1.GroupID and Parameter_ID < T1.Parameter_ID
      )  as Target_Value
    , [GroupID]
  from Parameter_List T1
  where Target_Value is null

  union all 

  select [Parameter_ID],[Parameters_Name],[Target_Value], [GroupID] from Parameter_List
  where Target_Value is not null
)
select [Parameters_Name],[Target_Value], [GroupID] from CTE 
order by Parameter_ID;

| Parameters_Name | Target_Value | GroupID |
|-----------------|--------------|---------|
|          Para_1 |         1000 |       2 |
|          Para_2 |         2000 |       2 |
|          Para_3 |         3000 |       2 |
|          Para_4 |         6000 |       2 |
|          Para_5 |         5000 |       2 |
|          Para_1 |         1450 |       3 |
|          Para_2 |         1200 |       3 |
|          Para_4 |         2650 |       3 |
|          Para_5 |         3000 |       3 |
|          Para_2 |         3000 |       4 |
|          Para_3 |         4000 |       4 |
|          Para_4 |         7000 |       4 |

DEMO SQL Fiddle

sum over is what you want

;with mycte as (
select 1 as parameter_id
,'para_1' as parameter_name
,1000 as target_value
,2 as groupid
,1 as sequence_no

union all

select 2 as parameter_id
,'para_2' as parameter_name
,2000 as target_value
,2 as groupid
,2 as sequence_no

union all

select 3 as parameter_id
,'para_3' as parameter_name
,3000 as target_value
,2 as groupid
,3 as sequence_no

union all

select 4 as parameter_id
,'para_4' as parameter_name
,NULL as target_value
,2 as groupid
,4 as sequence_no

union all

select 5 as parameter_id
,'para_5' as parameter_name
,5000 as target_value
,2 as groupid
,5 as sequence_no
)

Select parameter_name, isnull(target_value, sum (target_value) over(partition by groupid order by sequence_no)) ,groupid from mycte

Late to the party but here goes one more solution -

SELECT t.Parameters_Name, t.GroupID,
CASE when t.Target_Value IS NULL THEN 
                    (select sum(Target_Value) as runningTotal
                    from Parameter_List 
                    where GroupID = t.GroupID and Sequence_No <= t.Sequence_No) ELSE t.Target_Value END AS Target_Value  
FROM Parameter_List  t

You can try something new which is Applies to: SQL Server 2012 (11.x) through SQL Server 2017

SELECT Parameter_ID, 
    Parameters_Name,
    ISNULL(Target_Value,
        SUM(Target_Value) OVER (PARTITION BY GroupID   
                                ORDER BY Sequence_No  
                                ROWS UNBOUNDED PRECEDING)) AS Target_Value,
    GroupID, 
    Sequence_No
FROM test t 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM