SQL Server Running Difference between values of consecutive years [closed]

vawmfj5a  于 2023-05-05  发布在  其他
关注(0)|答案(3)|浏览(173)

Closed. This question needs details or clarity . It is not currently accepting answers.

Want to improve this question? Add details and clarify the problem by editing this post .

Closed 7 days ago.
Improve this question

I need to compute a running difference between InterimData values across different years.

YearMonthProviderProviderNameInterimData
202281A3866.666667
202291A3866.666667
2022121A3866.666667
202331A7416.666667
202332B7416.666667

Constant = 12800

Expected Output:
| Year | FinalValue | Logic |
| ------------ | ------------ | ------------ |
| 2022 | 8933.333333 | (Constant-Distinct InterimData of 2022 Year) |
| 2023 | 1516.666666 | (FinalValue of 2022 - Distinct interimData of 2023 Year) |

I've tried using the LAG function, but it's not working out as expected. I am using sql server 2022.

Can you please help me?

fcwjkofz

fcwjkofz1#

LAG can't help you here because it doesn't carry information from all previous records.

You could solve this problem by:

  • extracting your unique year-by-year values from your data
  • using a running sum, that stacks up all preceding InterimData values
  • subtracting your aggregated values from the constant.
SELECT Year_, 
       12800 - SUM(InterimData) OVER(ORDER BY Year_) AS FinalValue
FROM (SELECT DISTINCT Year_, InterimData FROM tab) cte

Output:

Year_FinalValue
20228933.333333
20231516.666666

Check the demo here .

nzk0hqpo

nzk0hqpo2#

with t as ( 
  select year, max(InterimData) val, row_number() over (order by year) rn
  from table_name group by year),
rec(year, val, rn) as (
  select year, 12800 - val, rn from t where rn = 1 union all
  select t.year, rec.val - t.val, t.rn from t join rec on rec.rn + 1 = t.rn )
select year, val from rec

dbfiddle demo

  1. Take distinct values per year, here done with aggregation and sum() in subquery t , also add row numbers,
  2. Use simple recursive query , in first row subtract from constant value, in next row previous minus current value.
oknrviil

oknrviil3#

you can use cte and window function I used recursive Query and everything is dynamic first you find min Year and calculate first formula to Min Year and Last formula to other Year

declare  @Constant int =12800
;with _list as(
    select *
    from (
            select *,ROW_NUMBER() over(Partition by Year order by Year) rw
            ,Max(InterimData) over(Partition by Year) as maxInterimData
            from Ta
    )a
    where rw=1
),
Years as (
            select   Min(Year) as minYear  from Ta
),
CTE as ( 
            select      e.[Year] as y,
                         @Constant -e.maxInterimData as  FinalValue,maxInterimData
            from _list e
            where Year=(select minYear from Years)
            UNION ALL 
            select e.[Year] as y,  
                FinalValue -e.maxInterimData as FinalValue,e.maxInterimData
            from _list e
            join CTE b on
                e.[Year]=b.y +1 )
select y,FinalValue from CTE

You can insert Base data with the following statements:

drop TABLE if exists  Ta
create table Ta(
Year    smallint ,Month smallint,Provider smallint, ProviderName varchar(100),  InterimData decimal(38,6)
)
INSERT INTO Ta(Year,Month,Provider,ProviderName,InterimData) VALUES(2022, 8, 1,'A',3866.666667)
INSERT INTO Ta(Year,Month,Provider,ProviderName,InterimData) VALUES(2022, 9,1,'A',3866.666667)
INSERT INTO Ta(Year,Month,Provider,ProviderName,InterimData)VALUES(2022,12,1,'A',3866.666667)
INSERT INTO Ta(Year,Month,Provider,ProviderName,InterimData) VALUES(2023,3,1, 'A',7416.666667)
INSERT INTO Ta(Year,Month,Provider,ProviderName,InterimData) VALUES(2023,3, 2, 'B', 7416.666667)
INSERT INTO Ta(Year,Month,Provider,ProviderName,InterimData) VALUES(2024,3, 2, 'B', 7416.666667)
INSERT INTO Ta(Year,Month,Provider,ProviderName,InterimData) VALUES(2025,3, 2, 'A', 7416.666667)
INSERT INTO Ta(Year,Month,Provider,ProviderName,InterimData) VALUES(2025,3, 2, 'B', 7416.666667)

相关问题