FIFO库存老化

时间:2016-01-29 19:37:02

标签: sql sql-server sql-server-2008 tsql fifo

提前道歉解释。任何帮助将不胜感激。

我们有下表:

enter image description here

此表包含6个存储桶:

  • 360:持有360天或以上的资产或负债
  • 181 - 360:181至360天之间的资产或负债
  • 91 - 180:91至180天之间的资产或负债
  • 61 - 90:61至90天之间的资产或负债
  • 31 - 60:31至60天之间的资产或负债
  • =< 30:持有30天或以下的资产或负债

我们想要应用以下逻辑来获得如下所示的结果:

enter image description here

逻辑如下:

  • 从第360列开始,从资产中减去负债。
  • 如果结果是负债,我们将资产留在较低的桶中,那么从下一列中减去资产,依此类推,直到我们要么经历所有资产桶,或者我们有0个资产和负债用于该桶。
  • 如果结果是资产,我们将负债留在较低的桶中,那么从下一栏中减去负债,依此类推,直到我们要么经历所有资产桶,或者我们有0桶资产和负债
  • 当我们从较高的桶(91-180)中减去较低的桶(31-60)时,如果我们设法完全清除剩余的资产或负债,并且仍然从较低的桶中保留一些资产或负债,那么然后,下部存储桶成为剩余部分,它将用于评估下一个存储桶。 (参见下面这个场景的例子)

所以设置:

enter image description here

将成为:

enter image description here

我试图避免使用循环,并希望使用集而不是游标来实现此目的。我自己有一些事情,但不能得到我需要的结果。 This article帮助但不完全符合我的需要。

生成测试数据的脚本:

CREATE TABLE #LINE ([Cusip] VARCHAR(32),
                    [TradingActivity] VARCHAR(10),
                    [NotionalAmount] DECIMAL (20,2),
                    [TradeDate]  DATE,
                    [ValDate] DATE)

INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-01-09','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-01-12','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-07-09','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-07-10','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-10-07','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-10-08','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-11-06','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-11-09','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-12-06','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-12-07','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-01-09','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-01-12','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-07-09','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-07-10','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-10-07','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-10-08','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-11-06','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-11-09','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-12-06','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-12-07','2016-01-07')
INSERT INTO #LINE VALUES('T0002','BUY','2000000.00','2015-01-09','2016-01-07')
INSERT INTO #LINE VALUES('T0002','SELL','1000000.00','2015-01-09','2016-01-07')
INSERT INTO #LINE VALUES('T0003','SELL','2000000.00','2015-07-09','2016-01-07')
INSERT INTO #LINE VALUES('T0003','BUY','1000000.00','2015-07-09','2016-01-07')
INSERT INTO #LINE VALUES('T0004','BUY','1000000.00','2015-10-07','2016-01-07')
INSERT INTO #LINE VALUES('T0004','SELL','2000000.00','2015-10-07','2016-01-07')
INSERT INTO #LINE VALUES('T0005','SELL','1000000.00','2015-11-06','2016-01-07')
INSERT INTO #LINE VALUES('T0005','BUY','2000000.00','2015-11-06','2016-01-07')
INSERT INTO #LINE VALUES('T0006','BUY','1000000.00','2015-11-07','2016-01-07')
INSERT INTO #LINE VALUES('T0006','SELL','1000000.00','2015-11-07','2016-01-07')
INSERT INTO #LINE VALUES('T0007','SELL','2000000.00','2015-12-07','2016-01-07')
INSERT INTO #LINE VALUES('T0007','BUY','2000000.00','2015-12-07','2016-01-07')
INSERT INTO #LINE VALUES('T0008','SELL','1000000.00','2016-01-07','2016-01-07')
INSERT INTO #LINE VALUES('T0008','BUY','2000000.00','2015-01-08','2016-01-07')
INSERT INTO #LINE VALUES('T0009','BUY','1000000.00','2016-01-07','2016-01-07')
INSERT INTO #LINE VALUES('T0009','SELL','2000000.00','2015-07-09','2016-01-07')
INSERT INTO #LINE VALUES('T0010','SELL','2000000.00','2016-01-07','2016-01-07')
INSERT INTO #LINE VALUES('T0010','BUY','1000000.00','2015-10-07','2016-01-07')
INSERT INTO #LINE VALUES('T0011','BUY','2000000.00','2016-01-07','2016-01-07')
INSERT INTO #LINE VALUES('T0011','SELL','1000000.00','2015-11-06','2016-01-07')
INSERT INTO #LINE VALUES('T0012','SELL','1000000.00','2016-01-07','2016-01-07')
INSERT INTO #LINE VALUES('T0012','BUY','1000000.00','2015-11-07','2016-01-07')
INSERT INTO #LINE VALUES('T0013','SELL','2000000.00','2015-12-07','2016-01-07')
INSERT INTO #LINE VALUES('T0013','BUY','2000000.00','2016-01-07','2016-01-07')
INSERT INTO #LINE VALUES('T0014','SELL','2000000.00','2015-12-03','2016-01-07')
INSERT INTO #LINE VALUES('T0014','BUY','1000000.00','2015-01-01','2016-01-07')
INSERT INTO #LINE VALUES('T0014','SELL','2000000.00','2015-07-02','2016-01-07')
INSERT INTO #LINE VALUES('T0014','BUY','2000000.00','2015-10-02','2016-01-07')
INSERT INTO #LINE VALUES('T0015B','SELL','1000000.00','2015-12-03','2016-01-07')
INSERT INTO #LINE VALUES('T0015A','BUY','4000000.00','2015-04-02','2016-01-07')
INSERT INTO #LINE VALUES('T0015A','SELL','3000000.00','2015-07-02','2016-01-07')
INSERT INTO #LINE VALUES('T0015B','BUY','2000000.00','2015-10-01','2016-01-07')
INSERT INTO #LINE VALUES('T0016B','SELL','2000000.00','2015-12-01','2016-01-07')
INSERT INTO #LINE VALUES('T0016A','BUY','3000000.00','2015-04-02','2016-01-07')
INSERT INTO #LINE VALUES('T0016A','SELL','4000000.00','2015-07-02','2016-01-07')
INSERT INTO #LINE VALUES('T0016B','BUY','1000000.00','2015-10-01','2016-01-07')
INSERT INTO #LINE VALUES('T0017A','SELL','3000000.00','2015-12-09','2016-01-07')
INSERT INTO #LINE VALUES('T0017B','SELL','2000000.00','2015-12-09','2016-01-07')
INSERT INTO #LINE VALUES('T0017A','BUY','4000000.00','2015-10-09','2016-01-07')
INSERT INTO #LINE VALUES('T0017B','BUY','1000000.00','2015-10-09','2016-01-07')
INSERT INTO #LINE VALUES('T0018B','SELL','2000000.00','2015-12-01','2016-01-07')
INSERT INTO #LINE VALUES('T0018A','BUY','4000000.00','2015-04-02','2016-01-07')
INSERT INTO #LINE VALUES('T0018B','BUY','1000000.00','2015-07-02','2016-01-07')
INSERT INTO #LINE VALUES('T0018A','SELL','3000000.00','2015-10-01','2016-01-07')
INSERT INTO #LINE VALUES('T0019B','BUY','8000000.00','2015-12-03','2016-01-07')
INSERT INTO #LINE VALUES('T0019A','SELL','1000000.00','2015-01-01','2016-01-07')
INSERT INTO #LINE VALUES('T0019B','BUY','5000000.00','2015-07-02','2016-01-07')
INSERT INTO #LINE VALUES('T0019A','SELL','7000000.00','2015-09-02','2016-01-07')
INSERT INTO #LINE VALUES('T0020B','SELL','8000000.00','2015-12-03','2016-01-07')
INSERT INTO #LINE VALUES('T0020A','SELL','1000000.00','2015-01-01','2016-01-07')
INSERT INTO #LINE VALUES('T0020B','BUY','5000000.00','2015-07-02','2016-01-07')
INSERT INTO #LINE VALUES('T0020A','BUY','7000000.00','2015-09-02','2016-01-07')

1 个答案:

答案 0 :(得分:0)

经过一些试验和错误后,这个实现给了我想要的结果:

CREATE TABLE #LINE ([Cusip] VARCHAR(32),
                    [TradingActivity] VARCHAR(10),
                    [NotionalAmount] DECIMAL (20,2),
                    [TradeDate]  DATE,
                    [ValDate] DATE)

INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-01-09','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-01-12','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-07-09','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-07-10','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-10-07','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-10-08','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-11-06','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-11-09','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-12-06','2016-01-07')
INSERT INTO #LINE VALUES('T0001_A','BUY','1000000.00','2015-12-07','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-01-09','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-01-12','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-07-09','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-07-10','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-10-07','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-10-08','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-11-06','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-11-09','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-12-06','2016-01-07')
INSERT INTO #LINE VALUES('T0001_B','SELL','1000000.00','2015-12-07','2016-01-07')
INSERT INTO #LINE VALUES('T0002','BUY','2000000.00','2015-01-09','2016-01-07')
INSERT INTO #LINE VALUES('T0002','SELL','1000000.00','2015-01-09','2016-01-07')
INSERT INTO #LINE VALUES('T0003','SELL','2000000.00','2015-07-09','2016-01-07')
INSERT INTO #LINE VALUES('T0003','BUY','1000000.00','2015-07-09','2016-01-07')
INSERT INTO #LINE VALUES('T0004','BUY','1000000.00','2015-10-07','2016-01-07')
INSERT INTO #LINE VALUES('T0004','SELL','2000000.00','2015-10-07','2016-01-07')
INSERT INTO #LINE VALUES('T0005','SELL','1000000.00','2015-11-06','2016-01-07')
INSERT INTO #LINE VALUES('T0005','BUY','2000000.00','2015-11-06','2016-01-07')
INSERT INTO #LINE VALUES('T0006','BUY','1000000.00','2015-11-07','2016-01-07')
INSERT INTO #LINE VALUES('T0006','SELL','1000000.00','2015-11-07','2016-01-07')
INSERT INTO #LINE VALUES('T0007','SELL','2000000.00','2015-12-07','2016-01-07')
INSERT INTO #LINE VALUES('T0007','BUY','2000000.00','2015-12-07','2016-01-07')
INSERT INTO #LINE VALUES('T0008','SELL','1000000.00','2016-01-07','2016-01-07')
INSERT INTO #LINE VALUES('T0008','BUY','2000000.00','2015-01-08','2016-01-07')
INSERT INTO #LINE VALUES('T0009','BUY','1000000.00','2016-01-07','2016-01-07')
INSERT INTO #LINE VALUES('T0009','SELL','2000000.00','2015-07-09','2016-01-07')
INSERT INTO #LINE VALUES('T0010','SELL','2000000.00','2016-01-07','2016-01-07')
INSERT INTO #LINE VALUES('T0010','BUY','1000000.00','2015-10-07','2016-01-07')
INSERT INTO #LINE VALUES('T0011','BUY','2000000.00','2016-01-07','2016-01-07')
INSERT INTO #LINE VALUES('T0011','SELL','1000000.00','2015-11-06','2016-01-07')
INSERT INTO #LINE VALUES('T0012','SELL','1000000.00','2016-01-07','2016-01-07')
INSERT INTO #LINE VALUES('T0012','BUY','1000000.00','2015-11-07','2016-01-07')
INSERT INTO #LINE VALUES('T0013','SELL','2000000.00','2015-12-07','2016-01-07')
INSERT INTO #LINE VALUES('T0013','BUY','2000000.00','2016-01-07','2016-01-07')
INSERT INTO #LINE VALUES('T0014','SELL','2000000.00','2015-12-03','2016-01-07')
INSERT INTO #LINE VALUES('T0014','BUY','1000000.00','2015-01-01','2016-01-07')
INSERT INTO #LINE VALUES('T0014','SELL','2000000.00','2015-07-02','2016-01-07')
INSERT INTO #LINE VALUES('T0014','BUY','2000000.00','2015-10-02','2016-01-07')
INSERT INTO #LINE VALUES('T0015B','SELL','1000000.00','2015-12-03','2016-01-07')
INSERT INTO #LINE VALUES('T0015A','BUY','4000000.00','2015-04-02','2016-01-07')
INSERT INTO #LINE VALUES('T0015A','SELL','3000000.00','2015-07-02','2016-01-07')
INSERT INTO #LINE VALUES('T0015B','BUY','2000000.00','2015-10-01','2016-01-07')
INSERT INTO #LINE VALUES('T0016B','SELL','2000000.00','2015-12-01','2016-01-07')
INSERT INTO #LINE VALUES('T0016A','BUY','3000000.00','2015-04-02','2016-01-07')
INSERT INTO #LINE VALUES('T0016A','SELL','4000000.00','2015-07-02','2016-01-07')
INSERT INTO #LINE VALUES('T0016B','BUY','1000000.00','2015-10-01','2016-01-07')
INSERT INTO #LINE VALUES('T0017A','SELL','3000000.00','2015-12-09','2016-01-07')
INSERT INTO #LINE VALUES('T0017B','SELL','2000000.00','2015-12-09','2016-01-07')
INSERT INTO #LINE VALUES('T0017A','BUY','4000000.00','2015-10-09','2016-01-07')
INSERT INTO #LINE VALUES('T0017B','BUY','1000000.00','2015-10-09','2016-01-07')
INSERT INTO #LINE VALUES('T0018B','SELL','2000000.00','2015-12-01','2016-01-07')
INSERT INTO #LINE VALUES('T0018A','BUY','4000000.00','2015-04-02','2016-01-07')
INSERT INTO #LINE VALUES('T0018B','BUY','1000000.00','2015-07-02','2016-01-07')
INSERT INTO #LINE VALUES('T0018A','SELL','3000000.00','2015-10-01','2016-01-07')
INSERT INTO #LINE VALUES('T0019B','BUY','8000000.00','2015-12-03','2016-01-07')
INSERT INTO #LINE VALUES('T0019A','SELL','1000000.00','2015-01-01','2016-01-07')
INSERT INTO #LINE VALUES('T0019B','BUY','5000000.00','2015-07-02','2016-01-07')
INSERT INTO #LINE VALUES('T0019A','SELL','7000000.00','2015-09-02','2016-01-07')
INSERT INTO #LINE VALUES('T0020B','SELL','8000000.00','2015-12-03','2016-01-07')
INSERT INTO #LINE VALUES('T0020A','SELL','1000000.00','2015-01-01','2016-01-07')
INSERT INTO #LINE VALUES('T0020B','BUY','5000000.00','2015-07-02','2016-01-07')
INSERT INTO #LINE VALUES('T0020A','BUY','7000000.00','2015-09-02','2016-01-07')

-- Assign LOT numbers to each record based on CUSIP, TradingActivity, and Bucket. And assign rankings to the buckets used for ordering later on.
IF OBJECT_ID('tempdb..#RollUp') IS NOT NULL
    DROP TABLE #RollUp;

       SELECT  A.[Cusip], 
             A.[TradingActivity], 
             A.[NotionalAmount],
             [LOT] =ROW_NUMBER() OVER (PARTITION BY A.[Cusip],A.[TradingActivity],CASE  WHEN DATEDIFF(day,A.[TradeDate],A.[ValDate]) BETWEEN 0 AND 30 THEN '0'  --'[=<30]' 
               WHEN DATEDIFF(day,A.[TradeDate],A.[ValDate]) BETWEEN 31 AND 60 THEN '1'  --'[31-60]' 
               WHEN DATEDIFF(day,A.[TradeDate],A.[ValDate]) BETWEEN 61 AND 90 THEN '2'  --'[61-90]' 
               WHEN DATEDIFF(day,A.[TradeDate],A.[ValDate]) BETWEEN 91 AND 180 THEN '3'  --'[91-180]' 
               WHEN DATEDIFF(day,A.[TradeDate],A.[ValDate]) BETWEEN 181 AND 360 THEN '4'  --'[181-360]'  
               WHEN DATEDIFF(day,A.[TradeDate],A.[ValDate]) > 360 THEN '5'  --'[+360]' 
               END ORDER BY A.[TradeDate] ) 
             ,
             [Bucket]= CASE WHEN DATEDIFF(day,[TradeDate],[ValDate]) BETWEEN 0 AND 30 THEN '0'  --'[=<30]' 
               WHEN DATEDIFF(day,[TradeDate],[ValDate]) BETWEEN 31 AND 60 THEN '1'  --'[31-60]' 
               WHEN DATEDIFF(day,[TradeDate],[ValDate]) BETWEEN 61 AND 90 THEN '2'  --'[61-90]' 
               WHEN DATEDIFF(day,[TradeDate],[ValDate]) BETWEEN 91 AND 180 THEN '3'  --'[91-180]' 
               WHEN DATEDIFF(day,[TradeDate],[ValDate]) BETWEEN 181 AND 360 THEN '4'  --'[181-360]'  
               WHEN DATEDIFF(day,[TradeDate],[ValDate]) > 360 THEN '5'  --'[+360]' 
               END INTO #RollUp
       FROM #Line AS A 
       ORDER BY [Cusip],[TradeDate]  

-- Apply (+/-) sign to NotionalAmount and derive the SUM of NotionalAmount based on  CUSIP, TradingActivity, and Bucket
IF OBJECT_ID('tempdb..#TEMP') IS NOT NULL
    DROP TABLE #TEMP;

       SELECT  A.[Cusip], 
             A.[Bucket],
             A.[LOT],  
             A.[NotionalAmount],
             [SignedNotionalAmount] = CASE WHEN A.[TradingActivity] = 'BUY' THEN  A.[NotionalAmount] ELSE 0-A.[NotionalAmount] END,
             A.[TradingActivity],  
             [SumNotionalAmount] = SUM(A.[NotionalAmount])OVER(PARTITION BY A.[Cusip],A.[TradingActivity], A.[Bucket] ) INTO #TEMP      
       FROM #RollUp AS A     
       ORDER BY    A.[Bucket] DESC,
                A.[LOT] ASC 

-- Rank the notional ammounts for each CUSIP based on TradeActivity
IF OBJECT_ID('tempdb..#TEMP2') IS NOT NULL
    DROP TABLE #TEMP2; 

       SELECT  A.[Cusip], 
             A.[Bucket], 
             [SumNotionalAmount] = SUM(A.[SignedNotionalAmount]),
             [SignedNotionalAmountRanked] = RANK() OVER( PARTITION BY A.[Cusip],CASE   WHEN SUM(A.[SignedNotionalAmount]) > 0 THEN 'BUY' 
                                                                ELSE 'SELL' END  
                                                ORDER BY A.Bucket DESC)  INTO #TEMP2
       FROM #TEMP AS A
       GROUP BY    A.[Cusip],  
                A.[Bucket] 


-- Calculate Sum of the Notional amount based on FIFO algorithm at CUSIP level and place in correct bucket(s)
IF OBJECT_ID('tempdb..#TEMP3') IS NOT NULL
    DROP TABLE #TEMP3; 

       SELECT  A.[Cusip],  A.[Bucket] AS ABucket,B.[Bucket] AS BBucket, A.[SumNotionalAmount] AS ASumNotionalAmount ,  B.[SumNotionalAmount]  AS BSumNotionalAmount, 
             [Bucket] = CASE WHEN ABS(A.[SumNotionalAmount])>ABS(B.[SumNotionalAmount])  THEN CASE A.[Bucket]  WHEN 0 THEN '=<30' 
                                    WHEN 1 THEN '31-60' 
                                    WHEN 2 THEN '61-90' 
                                    WHEN 3 THEN '91-180' 
                                    WHEN 4 THEN '181-360'  
                                    WHEN 5 THEN '+360' 
                                    END
                          WHEN ABS(A.[SumNotionalAmount])<ABS(B.[SumNotionalAmount])  THEN CASE B.[Bucket]  WHEN 0 THEN '=<30' 
                                    WHEN 1 THEN '31-60' 
                                    WHEN 2 THEN '61-90' 
                                    WHEN 3 THEN '91-180' 
                                    WHEN 4 THEN '181-360'  
                                    WHEN 5 THEN '+360' 
                                    END
                          WHEN (ABS(A.[SumNotionalAmount])=ABS(B.[SumNotionalAmount]) AND A.[SumNotionalAmount]>B.[SumNotionalAmount])  THEN CASE B.[Bucket]  WHEN 0 THEN '=<30' 
                                    WHEN 1 THEN '31-60' 
                                    WHEN 2 THEN '61-90' 
                                    WHEN 3 THEN '91-180' 
                                    WHEN 4 THEN '181-360'  
                                    WHEN 5 THEN '+360' 
                                    END
                          WHEN (ABS(A.[SumNotionalAmount])=ABS(B.[SumNotionalAmount]) AND A.[SumNotionalAmount]<B.[SumNotionalAmount])  THEN CASE A.[Bucket]  WHEN 0 THEN '=<30' 
                                    WHEN 1 THEN '31-60' 
                                    WHEN 2 THEN '61-90' 
                                    WHEN 3 THEN '91-180' 
                                    WHEN 4 THEN '181-360'  
                                    WHEN 5 THEN '+360' 
                                    END
                          ELSE CASE A.[Bucket]  WHEN 0 THEN '=<30' 
                                    WHEN 1 THEN '31-60' 
                                    WHEN 2 THEN '61-90' 
                                    WHEN 3 THEN '91-180' 
                                    WHEN 4 THEN '181-360'  
                                    WHEN 5 THEN '+360' 
                                    END
                      END ,
                       [RunningSumNotionalAmount] = SUM(A.[SumNotionalAmount]+B.[SumNotionalAmount] )OVER(PARTITION BY A.[Cusip] )  
                      ,
             [SumNotionalAmount] = CASE  WHEN B.[Bucket] IS NOT NULL THEN A.[SumNotionalAmount]+B.[SumNotionalAmount] 
                                    ELSE A.SumNotionalAmount 
                                END INTO #TEMP3
       FROM    #TEMP2 AS A LEFT OUTER JOIN 
             #TEMP2 AS B ON  A.[Cusip] = B.[Cusip] AND
                          A.[SignedNotionalAmountRanked] = B.[SignedNotionalAmountRanked] AND
                          A.[Bucket] <>  B.[Bucket]  
       WHERE  (A.Bucket > B.Bucket  OR 
             B.Bucket IS NULL) 
       ORDER BY    A.Cusip,
                A.Bucket

IF OBJECT_ID('tempdb..#TEMP4') IS NOT NULL
    DROP TABLE #TEMP4; 
SELECT *, (SELECT  SUM(i.[SumNotionalAmount])
             FROM    #TEMP3 AS i  
             WHERE   i.[Cusip] = s.[Cusip] AND                    
                    i.[Bucket] < s.[Bucket] 
               ) AS RollingStock , HasRemainder =  ABS([RunningSumNotionalAmount]) + s.[SumNotionalAmount]  INTO #TEMP4
FROM #TEMP3   AS s 



 SELECT [Cusip],
       [=<30],
       [31-60],
       [61-90],
       [91-180],
       [181-360],
       [+360]
FROM 
(   SELECT  [Cusip],
       [Bucket], 
       [SumNotionalAmount] = CASE    WHEN    SUM([RollingStock]+ [HasRemainder] )OVER(PARTITION BY  [Cusip] ) IS NOT NULL AND 
                                    [HasRemainder] IS NOT NULL THEN ISNULL([RollingStock],0) 
                             ELSE [SumNotionalAmount] 
                        END 
    FROM #TEMP4 ) p
PIVOT
(   SUM([SumNotionalAmount] )
    FOR [Bucket] IN (   [=<30],
                    [31-60],
                    [61-90],
                    [91-180],
                    [181-360],
                    [+360]  )
) AS pvt

结果:

enter image description here

相关问题