Получить сумму значений до следующей строки в таблице

У меня есть таблица Parameter_List с полями Parameter_ID, Parameters_Name, Target_Value, GroupID и Sequence_No. Значения могут быть

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  

Как видите, Target_Value для Para_4 всегда NULL. Теперь, когда я хочу отобразить записи, я хочу, чтобы значение Para_4 было суммой Target_Value параметров выше Para_4 для этой группы. Например, для GroupID 2 значение Para_4 должно быть суммой первых трех строк. В таблице есть столбец Sequence_No. Таким образом, Para_4 должен иметь 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
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
2
0
197
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Один из подходов состоит в том, чтобы вычислить кумулятивную сумму Target_Value в CTE, а затем обновить этот CTE, где бы Target_Value был 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;

это потрясающе!

ITWeiHan 22.05.2018 07:19

@ITWeiHan Глянь сюда за очень хорошее введение в расширение оконных функций SQL Server.

Tim Biegeleisen 22.05.2018 07:22
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

Суммировать это то, что вы хотите

;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
Ответ принят как подходящий

Поздно к вечеринке, но вот еще одно решение -

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

Вы можете попробовать что-нибудь новенькое - 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 

Другие вопросы по теме