簡體   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