2016-09-26 48 views
1

我有以下情況:我有屬於許多投資的事務列表。交易記錄包含投資標識符,日期和總金額,但不包含運行餘額。SQL - 一次根據多個實體的先前行值計算行值

交易表:

+------------+------------+--------+ 
| Investment | Date  | Gross | 
+------------+------------+--------+ 
| A   | 2015-01-01 | +200 | 
| B   | 2015-06-30 | +500 | 
| C   | 2016-01-10 | +300 | 
| A   | 2016-08-15 | +100 | 
| A   | 2016-09-21 | -300 | 
+------------+------------+--------+ 

平衡被保存在一個單獨的表,並且始終是最新的:

資產負債表:

+------------+------------+ 
| Investment | Balance | 
+------------+------------+ 
| A   |   0 | 
| B   |  500 | 
| C   |  300 | 
+------------+------------+ 

我想什麼要做的是獲得每筆交易的運行餘額一次只能點。

因此,舉例來說,如果我想從2016年1月1日展示交易,以2016年8月31日爲投資A,B和C,與正在運行的平衡,我會得到這樣的:

結果:

+------------+------------+--------+-------------+ 
| Investment | Date  | Gross | End Balance | 
+------------+------------+--------+-------------+ 
| C   | 2016-01-10 | 300 |   300 | 
| A   | 2016-08-15 | 100 |   300 | 
+------------+------------+--------+-------------+ 

我想這樣做沒有迭代器,因爲我認爲它效率低下。此外,使用餘額表並從當前餘額向後工作將是理想的,因爲投資可能有許多交易,而我通常只需要顯示一些交易,而且通常需要顯示較少的交易。

非常感謝您的幫助。

+0

結果您是如何得到A的最終餘額的? – Kostya

+0

@Kostya我沒有當前餘額減去所有交易的總價值:所以,0 - ( - 300)= 300 – KJY

回答

0

使用CROSS APPLY來獲得運轉平衡

SELECT t.Investment, t.Date, t.Gross, b.Balance 
FROM Transaction t 
     CROSS APPLY 
     (
      SELECT balance = SUM(x.Gross) 
      FROM Transaction x 
      WHERE x.Invenstment = t.Investment 
      AND x.Date <= t.Date 
     ) b 
WHERE t.Date >= '2016-01-01' 
AND t.Date <= '2016-08-31' 

編輯:處理一個以上的反式同日

; with Trans as 
(
    SELECT *, rn = row_number() over (partition by Investment order by Date) 
    FROM Transaction 
) 
SELECT t.Investment, t.Date, t.Gross, b.Balance 
FROM Trans t 
     CROSS APPLY 
     (
      SELECT balance = SUM(x.Gross) 
      FROM Trans x 
      WHERE x.Invenstment = t.Investment 
      AND x.rn <= t.rn 
     ) b 
WHERE t.Date >= '2016-01-01' 
AND t.Date <= '2016-08-31' 
+0

謝謝@Squirrel。該解決方案讓我到: \t SELECT t.Investment,t.Date,t.Gross,b.balance \t FROM事務T \t \t OUTER APPLY \t \t( \t \t \t SELECT餘額=(CURRENT_BALANCE - 總和( t2.Gross)) \t \t \t FROM餘額X \t \t \t \t INNER JOIN事務T2上t2.Investment = x.Investment \t \t \t WHERE x.Investment = t.Investment \t \t \t AND t2.Date> t。日期 \t \t \t GROUP BY x.Current_Balance \t \t)b \t WHERE t.Date> = '2016年1月1日' \t AND t.Date <= '2016年8月31日' 但現在我在同一天有兩筆交易時有問題。任何想法分別對待他們?再次感謝 – KJY

+0

@KJY。編輯查詢 – Squirrel

0

與下面的查詢嘗試,如果你使用的是SQL 2012年或更高版。

;with cte_1 
    AS (SELECT Investment,Date 
       ,Gross 
       ,SUM(Gross) OVER(Partition by Investment ORDER BY Date 
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) EndBalance 
       ,ROW_NUMBER()OVER(Partition By Investment Order By Date DESC)RNO 
      FROM Transaction 
     WHERE Date between @starDate AND @endDate 
     ) 

    SELECT  * 
    FROM cte_1 A 
    WHERE RNO =1