简体   繁体   中英

sql update query on temporary table

I have a temporary table like below :

  Date    Fund  NotAdded    Dividend
1/1/2017    A     0           0
1/2/2017    A     0           0
1/3/2017    A   100           0
1/4/2017    A     0         200
1/5/2017    A    50          50
1/1/2017    B     0           0
1/2/2017    B   100           0
1/3/2017    B     0         200
1/4/2017    B     0           0

I want to run a update query on above table in a way that I will get result like below:

Date      Fund  NotAdded    Dividend   Notional
1/1/2017    A     0           0         5000 (this value is known)
1/2/2017    A     0           0         5000
1/3/2017    A   100           0         5100
1/4/2017    A     0         200         5300
1/5/2017    A    50          50         5400
1/1/2017    B     0           0         2000
1/2/2017    B   100           0         2100  
1/3/2017    B     0         200         2300
1/4/2017    B     0           0         2300

For each fund, default Notional value is known. ie in above example 5000 for fund A and 2000 for fund B.

I tried but not able to get the desired output. Any help!!!

You seem to want a cumulative sum of NotAdded and Dividend plus some random number. That latter I can't help with.

In SQL Server 2012+, you would use the cumulative sum function. In SQL Server 2008, you can use a later join ( apply ) or correlated subquery:

select t.*,
       (select sum(t2.NotAdded) + sum(t2.Dividend)
        from #temp t2
        where t2.fund = t.fund and
              t2.date <= t.date
       ) as Cumulative
from #temp t;

You can add the "known" value to cumulative to get the final value.

If you want this as an update:

update t
    set notional = notional + 
                   (select sum(t2.NotAdded) + sum(t2.Dividend)
                    from #temp t2
                    where t2.fund = t.fund and
                          t2.date <= t.date
                   )
    from #temp t;

This assumes that notional starts with the value in question.

You may use a COMPUTED column with a LAG function to SUM your columns considering the preceding row value..

Just OVER against your Fund and Date columns. The use of a primary key would be preferred, but if you've got none I guess it'll do the job for now.

Assuming that this is once off issue and not a permanent issue. I have come up with the following solution based on the following link :

How to get cumulative sum

I will do brief explanation of what I have done and then you can look at the code below.

First I created a temp table to imitate your temp table with one change, I insert an identity(1,1). This is required for the calculation part.

Then I inserted the data you had with the "known value" for the first row with fund type a (5000) and the first fund type b (2000).

Then there is two inserts into a temp table where the first main table joins onto itself and adds its NotAdded + Dividend + Notional values together from the second higher id (identity field) to the lower id.

After that all that is left to do is update your original table where the id's match. Please see code below.

--create temp table
DECLARE @TEMP TABLE 
(
    [id] INT IDENTITY(1,1), 
    [DATE] [datetime] NULL,
    [Fund] [varchar](1) NULL,
    [NotAdded] [int] NULL,
    [Dividend] [int] NULL,
    [Notional] [int] NULL   
)


--insert into temp table with first known value
INSERT INTO @TEMP ([DATE], [Fund], [NotAdded], [Dividend], Notional)
VALUES  ('1/1/2017','A',0,0,5000), --First value of A is known
        ('1/2/2017','A',0,0,0),
        ('1/3/2017','A',100,0,0),
        ('1/4/2017','A',0,200,0),
        ('1/5/2017','A',50,50,0),
        ('1/1/2017','B',0,0,2000), --First value of B is known
        ('1/2/2017','B',100,0,0),
        ('1/3/2017','B',0,200,0),
        ('1/4/2017','B',0,0,0)

--select into temp table for type a so that we can update the @temp table later 
SELECT T.id, T.Fund, T.NotAdded, T.Dividend, SUM(T2.NotAdded + T2.Dividend + T2.Notional)  AS Notional_Sum
INTO #TEMP_A
FROM @TEMP T 
    INNER JOIN @TEMP t2 on T.id >= t2.id
                        AND T2.Fund = T.Fund
WHERE 1=1
    AND T.Fund = 'A'
GROUP BY T.id, T.Fund,T.NotAdded, T.Dividend
ORDER BY T.id

--select into temp table for type b so that we can update the @temp table later 
SELECT T.id, T.Fund, T.NotAdded, T.Dividend, SUM(T2.NotAdded + T2.Dividend + T2.Notional)  AS Notional_Sum
INTO #TEMP_B
FROM @TEMP T 
    INNER JOIN @TEMP t2 on T.id >= t2.id
                        AND T2.Fund = T.Fund
WHERE 1=1
    AND T.Fund = 'B'
GROUP BY T.id, T.Fund,T.NotAdded, T.Dividend
ORDER BY T.id

--finally do updates
UPDATE T
SET T.Notional = TTS.Notional_Sum
FROM @TEMP T
        INNER JOIN #TEMP_A TTS ON TTS.id = T.id
WHERE 1=1

UPDATE T
SET T.Notional = TTS.Notional_Sum
FROM @TEMP T
        INNER JOIN #TEMP_B TTS ON TTS.id = T.id
WHERE 1=1


--select to view
SELECT  * FROM @TEMP

--drop temp tables
DROP TABLE #TEMP_A, #TEMP_B

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