我有以下情况:我有一份属于许多投资的交易清单。交易记录包含投资标识符,日期和总金额,但不包括运行余额。
交易表:
+------------+------------+--------+
| 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 |
+------------+------------+--------+-------------+
我想在没有迭代器的情况下理想地执行此操作,因为我认为它效率低下。此外,理想的情况是使用余额表并从当前余额向后工作,因为当我通常只需要显示一些和最近的那些时,投资可能有很多交易。 / p>
非常感谢你的帮助。
答案 0 :(得分: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'
编辑:处理多个具有相同日期的trans
; 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'
答案 1 :(得分: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