2016-09-26 37 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