2016-01-29 351 views
1

提前道歉解释。任何帮助,将不胜感激。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') 
+0

我认为你需要做一些工作,而不是在这里定义你的业务逻辑...... – JonH

+0

你的解释很不错,但有点混乱,你可以用样本数据重现那些步骤,以便我们更好地理解它? –

+2

这听起来像是在FIFO基础上消耗库存的变化。 [This](http://stackoverflow.com/questions/9420173/sql-subtracting-a-depleting-value-from-rows/9421009#9421009)答案可能会提供一些提示。 – HABO

回答

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