SQL Server中LAG的替代方法

问题描述

免责声明:sql Server编程的新功能

我目前正在使用sql无法进行计算。

基本上,这是一个具有期初余额的计算,某些计算取决于期初余额和期末余额。该表的最终结果应如下:

| Employee  | ROWN |Balance_year1 | O_balance | calc   | C_balance |
--------------------------------------------------------------------
| Emp1      |  1   | 1000         | 1000      | 20     | 1020      |
| Emp1      |  2   | 1000         | 1020      | 20.4   | 1040.4    | 
| Emp1      |  3   | 1000         | 1040.4    | 20.808 | 1061.208  | 
| Emp2      |  1   | 2000         | 2000      | 40     | 2040      |
| Emp2      |  2   | 2000         | 2040      | 40,8   | 2080,8    |
| Emp2      |  3   | 2000         | 2080,8    | 41,616 | 2122,416  |

直到现在我编写的代码如下:

WITH table1 AS (
    SELECT
       *,[O_balance] = LAG([C_balance],1,[Balance_year1]) OVER (PARTITION BY [Employee] ORDER BY [ROWN] ASC)
    FROM dataset
),table2 AS (
    SELECT 
       *,[calc]      = --Some calculations that depends on the [C_balance] from the row before
    FROM table1
)
SELECT 
    *,[O_balance],[calc],[C_balance] = [O_balance] + [calc]  
FROM table2

我在桌子上遇到的问题是:

  1. 在第一个CTE中使用[C_balance]时不会进行计算,因此无法运行。 (无效的列名[C_balance]
  2. [C_balance]中使用[calc]时计算不正确。

我想您可以计算表的行后行,也可以将[C_balance]保存在变量中以在整个运行过程中对其进行更新,但是idk?

我希望你们中的一个能帮助我-斗争是真实的:-)谢谢!

解决方法

您可以使用递归CTE进行所需的操作:

with cte as (
      select employee,rown,balance,balance as o_balance,balance * 1.02 as c_balance
      from dataset
      where rown = 1
      union all
      select d.employee,d.rown,d.balance,cte.c_balance,cte.c_balance * 1.02
      from cte join
           dataset d
           on cte.employee = d.employee and d.rown = cte.rown + 1
    )
select *
from cte;

我在猜测您的计算是什么,但这适用于您提供的数据。

,

对我来说,这似乎是一个运行中的问题(并且该问题已标记为问题,因此我将继续讨论)。首先,代码:

> pip -V
pip 20.2.2 from /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/pip (python 3.7)

我在这里使用通用表表达式只是为了易于使用-第一个表以可消耗格式获取数据,第二个表显示中间步骤。最终查询显示我的计算结果和您的计算结果相同。 “魔术”是with d as ( select * from (values ('Emp1',1,1000,20,1020 ),('Emp1',2,1020,20.4,1040.4 ),3,1040.4,20.808,1061.208 ),('Emp2',2000,40,2040 ),2040,40.8,2080.8 ),2080.8,41.616,2122.416 ) ) as x(Employee,ROWN,Balance_year1,O_balance,calc,C_balance) ),c as ( select *,balance_year1 + sum(calc) over (partition by employee order by rown) as myCalc from d ) select *,C_balance - myCalc from c 位。在相当现代的SQL版本中(2012年iirc推出,甚至更早),您可以执行此操作以获取总和。