T-SQL:自引用计算字段

T-SQL: Self-Referencing calculated field

我正在尝试根据现有 table 计算每日日间交易总数,该现有 table 提供连续五天 window 内日间交易的累计数量(仅限工作日).数据集非常简单,但是,如果不求助于无休止的子查询链,我似乎无法计算它。具有挑战性的部分是,在每个交易日结束时,五天前的日间交易总数现在到期并从滚动总数中删除。

这是我的数据集 (table):

这是我需要的最终结果:

请注意,底部的前四行(最旧的日期)以黄色突出显示非常容易计算,因为 11/09 是起点,没有之前的日间交易,因此不会删除日间交易(过期)直到四个工作日后(11 月 13 日)。

从那里,我不知道该怎么办。似乎我尝试的任何事情都只是一个计算字段,需要在过去的四行中引用自己(它自己的结果)。至少,部分计算会。计算本质上只是 = [截至今天的累计“日间交易”-(截至前一天的累计“日间交易”-前四天的“每日总计”)]。同样,数据集一开始只包含工作日。递归 CTE 是否适用于此?

备注 1:我不需要有关滚动累积“日内交易”字段的帮助。这已经为我自动填充了。我只需要帮助计算“每日总计”(每天的新日交易。

备注 2:“日间交易”就是在同一天买卖同一只股票。它是一对一匹配同一股票的买单和卖单。

备注3:方案需要兼容IBM Netezza规则,最好。

这可能不是最优雅的解决方案,但它应该给出正确的答案。

DECLARE @currentDate date 
DECLARE @expiredTrades int 
DECLARE @yesterday int
DECLARE @salesDataTable TABLE
(
    dates date,
    day_trades int,
    daily_total int NULL
)

INSERT INTO @salesDataTable (dates, day_tradeS, daily_total) VALUES
('2019-01-01', 10, 10),
('2019-01-02', 27, 17),
('2019-01-03', 28, 1),
('2019-01-04', 28, 0),
('2019-01-05', 24, NULL),
('2019-01-06', 7, NULL),
('2019-01-07', 11, NULL),
('2019-01-08', 11, NULL),
('2019-01-09', 18, NULL),
('2019-01-10', 18, NULL),
('2019-01-11', 56, NULL),
('2019-01-12', 61, NULL),
('2019-01-13', 56, NULL),
('2019-01-14', 68, NULL),
('2019-01-15', 48, NULL),
('2019-01-16', 52, NULL),
('2019-01-17', 54, NULL)

WHILE 1 = (SELECT TOP 1 1 FROM @salesDataTable WHERE daily_total IS NULL)
BEGIN
    SELECT TOP 1 @currentDate = dates
    FROM @salesDataTable
    WHERE daily_total IS NULL
    ORDER BY dates
    
    SELECT 
        @expiredTrades = LAG (daily_total, 4, 0) OVER (ORDER BY dates),
        @yesterday = LAG (day_trades, 1, 0) OVER (ORDER BY dates)
    FROM @salesDataTable
    WHERE dates <= @currentDate

    UPDATE @salesDataTable
    SET daily_total = day_trades - (@yesterday - @expiredTrades)
    WHERE dates = @currentDate
END

SELECT * 
FROM @salesDataTable
declare @t table(dates date, day_trades int);

insert into @t(dates, day_trades)
values
('20201109', 10), ('20201110', 27), ('20201111', 28), ('20201112', 28), ('20201113', 24),
('20201116', 7), ('20201117', 11), ('20201118', 11), ('20201119', 18), ('20201120', 18),
('20201123', 56), ('20201124', 61), ('20201125', 56), ('20201127', 68), ('20201130', 48),
('20201201', 52), ('20201202', 54);


select dates, day_trades, sum(prevdiff) over(partition by grp order by dates) as dailytotal
from
(
select *, 
    row_number() over(order by dates)%4 as grp,
    day_trades - lag(day_trades, 1, 0) over(order by dates) as prevdiff
from @t
) as t
order by dates desc