2016-07-06 7 views
0

私はこの1時間で私の頭を掻いていますが、次の表の行に$ 30の支払い額を割り当てる方法を見つけることができないようです。SQL Serverはアイテムに支払いを割り当てます

私には以下の項目があります。負の金額は、顧客が負債であり、その金額を負っていることを意味します。顧客が30ドルを支払うと仮定すると、それをアイテムに割り当てる必要があります。

ItemId        amount sDATE 
BD98E890-C7F8-47F4-9125-A68A88DD178D -10 2016-01-04 00:00:00.000 
7E047DE6-0DB7-4EDB-A751-C43BBD4610E5 -20 2016-01-05 00:00:00.000 
5004AE1F-2A15-47E5-96FF-69A6C7D35521 -10 2016-01-06 00:00:00.000 

$ 30の支払いの場合、出力は次のようになります。

itemId         BeforeAllocation AfterAllocation LeftToAllocate sDate 
BD98E890-C7F8-47F4-9125-A68A88DD178D -10     0    30    2016-01-04 00:00:00.000 
7E047DE6-0DB7-4EDB-A751-C43BBD4610E5 -20     0    20    2016-01-05 00:00:00.000 
5004AE1F-2A15-47E5-96FF-69A6C7D35521 -10     -10    0    2016-01-06 00:00:00.000 

となります。お客様が出力例の部分金額を25米ドル支払っている場合は、出力が必要です。

itemId         BeforeAllocation AfterAllocation LeftToAllocate sDate 
    BD98E890-C7F8-47F4-9125-A68A88DD178D -10     0    25    2016-01-04 00:00:00.000 
    7E047DE6-0DB7-4EDB-A751-C43BBD4610E5 -20     -5    15    2016-01-05 00:00:00.000 
    5004AE1F-2A15-47E5-96FF-69A6C7D35521 -10     -10    0    2016-01-06 00:00:00.000 

コード:

Create table #temp(ItemId UNIQUEIDENTIFIER , amount INT, sDATE DATETIME) 

INSERT INTO #temp 
     (ItemId, 
      amount, 
      sDATE) 
VALUES ( NEWID(),-10,'2016-01-04'), 
     ( NEWID(),-20,'2016-01-05'), 
     ( NEWID(),-10,'2016-01-06') 


SELECT * FROM (
SELECT 'BD98E890-C7F8-47F4-9125-A68A88DD178D' itemId, -10 BeforeAllocation, 0 AfterAllocation, 30 LeftToAllocate, '2016-01-04 00:00:00.000' sDate  
UNION 
SELECT '7E047DE6-0DB7-4EDB-A751-C43BBD4610E5' itemId, -20 BeforeAllocation, 0 AfterAllocation, 20 LeftToAllocate, '2016-01-05 00:00:00.000' sDate 
UNION 
SELECT '5004AE1F-2A15-47E5-96FF-69A6C7D35521' itemId, -10 BeforeAllocation, -10 AfterAllocation,0 LeftToAllocate, '2016-01-06 00:00:00.000' sDate 
)s 
ORDER BY sdate 

SELECT * FROM (
SELECT 'BD98E890-C7F8-47F4-9125-A68A88DD178D' itemId, -10 BeforeAllocation, 0 AfterAllocation, 25 LeftToAllocate, '2016-01-04 00:00:00.000' sDate  
UNION 
SELECT '7E047DE6-0DB7-4EDB-A751-C43BBD4610E5' itemId, -20 BeforeAllocation, -5 AfterAllocation, 15 LeftToAllocate, '2016-01-05 00:00:00.000' sDate 
UNION 
SELECT '5004AE1F-2A15-47E5-96FF-69A6C7D35521' itemId, -10 BeforeAllocation, -10 AfterAllocation,0 LeftToAllocate, '2016-01-06 00:00:00.000' sDate 
)s 
ORDER BY sdate 

答えて

0
  1. R unning T BeforeAllocationの otal(すなわち、この行のBeforeAllocationの和と先行するすべての行を記録するために、式BeforeAllocationRTを計算)。 SQL Server 2012以降を使用している場合は、ウィンドウ関数を使用できます。そうでない場合は、不器用なサブ表現が必要です。正確な手順については、this questionを参照してください。

  2. AfterAllocationLeftToAllocateの式を計算

    SELECT Allocation = CASE 
        WHEN BeforeAllocationRT + @Payment > 0 
         -- pay full amount for this item 
         THEN [email protected] 
        WHEN BeforeAllocationRT + @Payment > @BeforeAllocation 
         -- pay partial amount for this item 
         THEN -(@[email protected]) 
        ELSE 
         -- pay nothing for this item 
         0 
        END 
    , ... 
    
  3. を割り当てる量の式を計算します。

    SELECT 
        AfterAllocation = BeforeAllocation + Allocation 
        ,LeftToAllocate = CASE WHEN [email protected]>0 THEN @Payment-BeforeAllocationRT ELSE 0 END 
        ,... 
    
  4. CTEまたは部分式を使用して1,2,3を結合します。

免責事項:私は現在SQL Serverインスタンスにアクセスすることはできませんので、これはテストされていません。

0

DECLARE @PaidAmout INT = 30 

;WITH CTE AS 
(
    SELECT ItemId, amount, sDATE, ROW_NUMBER() OVER(ORDER BY sDATE) AS RowNo 
    FROM #temp 
), 
Amount AS 
(
    SELECT ItemId, 
      RowNo, 
      amount AS BeforeAllocation, 
      0 AS AfterAllocation, 
      @PaidAmout AS LeftToAllocate, 
      sDATE, 
      @PaidAmout + Amount AS LeftAmount 
    FROM CTE 
    WHERE RowNo = 1 

    UNION ALL 
    SELECT c.ItemId, 
      c.RowNo, 
      c.amount AS BeforeAllocation, 
      CASE WHEN a.LeftAmount + c.Amount < 0 THEN a.LeftAmount + c.Amount ELSE 0 END AS AfterAllocation, 
      CASE WHEN a.LeftAmount < 0 THEN 0 ELSE a.LeftAmount END AS LeftToAllocate, 
      c.sDATE, 
      a.LeftAmount + c.Amount AS LeftAmount 
    FROM CTE c 
    INNER JOIN Amount a ON a.RowNo + 1 = c.RowNo 
) 

SELECT ItemId, 
     BeforeAllocation, 
     AfterAllocation, 
     LeftToAllocate, 
     sDATE 
FROM Amount 
、これを試してみてください
関連する問題