簡體   English   中英

如何從以前的 window 分區中獲取 first_value

[英]How to get first_value from previous window partition

我想在查詢中顯示前一天的 BalanceEndOfYesterday 值,如下所示。

| Date       | Amout | BalanceEndOfDay | BalanceEndOfYesterday |
|------------|-------|-----------------|-----------------------|
| 2020-04-30 | 10    | 130             | 80                    |
| 2020-04-30 | 20    | 130             | 80                    |
| 2020-04-30 | 30    | 130             | 80                    |
| 2020-04-30 | -10   | 130             | 80                    |
| 2020-04-29 | 50    | 80              | 0                     |
| 2020-04-29 | -10   | 80              | 0                     |
| 2020-04-29 | 40    | 80              | 0                     |

我的查詢是

SELECT 
    BalanceEndOfDay ,
    first_value(BalanceEndOfDay) OVER (ORDER BY Date DESC) -- here is some sort of window needed
FROM AccountTransactions

您可以使用apply

SELECT at.*, COALESCE(at1.BalanceEndOfDay, 0) AS BalanceEndOfYesterday
FROM AccountTransactions at OUTER APPLY
     ( SELECT TOP (1) at1.BalanceEndOfDay
       FROM AccountTransactions at1
       WHERE at1.Date < at.Date
       ORDER BY at1.Date DESC
     ) at1;

編輯:如果你只想要昨天的余額,那么你可以使用dateadd()

SELECT DISTINCT at.*, COALESCE(at1.balanceendofday, 0) AS BalanceEndOfYesterday
FROM AccountTransactions at LEFT JOIN
     AccountTransactions at1
     ON at1.date = dateadd(day, -1, at.date);

我們可以在這里使用LAG ,首先按日期聚合以獲得每個日期的單個日終余額。 然后,我們可以將您的表格加入到此結果中,以提取昨天的日終余額。

WITH cte AS (
    SELECT Date, MAX(BalanceEndOfDay) AS BalanceEndOfDay,
        LAG(MAX(BalanceEndOfDay), 1, 0) OVER (ORDER BY Date) As BalanceEndOfYesterday
    FROM AccountTransactions
    GROUP BY Date
)

SELECT
    a1.Date,
    a1.Amount,
    a1.BalanceEndOfDay,
    a2.BalanceEndOfYesterday
FROM AccountTransactions a1
INNER JOIN cte a2
    ON a1.Date = a2.Date
ORDER BY
    a1.Date DESC;

下面演示的屏幕截圖

演示

如果您只想使用 window 函數來執行此操作,您可以使用:

select at.*,
       max(case when prev_date = dateadd(day, -1, date) then prev_BalanceEndOfDay end) over (partition by date) as prev_BalanceEndOfDay
from (select at.*,
             lag(BalanceEndOfDay) over (order by date) as prev_BalanceEndOfDay,
             lag(date) over (order by date) as prev_date
      from accounttransactions at
     ) at;

注意:這將“前一天”解釋為正好是前一天。 它的意思是“數據中的前一天”,那么第一個比較應該只是max(case when prev_date <> date. . . )

是一個 db<>fiddle。

請注意,在完全支持range window 規范的數據庫中,這可以直接使用如下邏輯完成:

max(BalanceEndOfDay) over (order by datediff(day, '2000-01-01', date)
                           range between 1 preceding and 1 preceding
                          )

唉,SQL 服務器不支持此(標准)功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM