繁体   English   中英

SQL Server 中 LAG() 的替代方法

[英]Alternative to LAG() in SQL Server

免责声明: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. [C_balance]在第一个 CTE 中使用时没有计算,因此无法运行。 (无效的列名[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;

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

对我来说,这看起来像是一个运行总和问题(并且这个问题被标记为这样,所以我将继续进行)。 首先,代码:

with d as (
    select * from (values
        ('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  )
    ) 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

我在这里使用通用表表达式只是为了便于使用 - 第一个以可使用的格式获取数据,第二个显示中间步骤。 最后的查询显示我的计算和你的计算得出相同的答案。 “魔术”是sum(calc) over (partition by employee order by rown)位。 在相当现代的 SQL 版本(在 2012 iirc 中引入,但可能更早)中,您可以这样做以获得运行总和。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM