微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

T-SQL:自引用计算字段

如何解决T-SQL:自引用计算字段

我正在尝试根据现有表格计算日间交易的每日总数,该表提供了滚动的五天窗口(仅限工作日)内的日间交易累计数量。数据集非常简单,但是,我似乎无法在不必求助于无穷无尽的子查询链的情况下进行计算。具有挑战性的部分是,在每个交易日结束时,五天前的日内交易总数现在到期并从滚动总数中删除

这是我的数据集(表格):

enter image description here

这是我需要的最终结果:

enter image description here

请注意,底部(最旧的日期)以黄色突出显示的前四行非常容易计算,因为 11/09 是起点,没有之前的日内交易,因此不会删除日内交易(过期)直到四个工作日后(2013 年 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',0),('2019-01-05',24,NULL),('2019-01-06',7,('2019-01-07',11,('2019-01-08',('2019-01-09',18,('2019-01-10',('2019-01-11',56,('2019-01-12',61,('2019-01-13',('2019-01-14',68,('2019-01-15',48,('2019-01-16',52,('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',('20201110',27),('20201111',28),('20201112',('20201113',24),('20201116',7),('20201117',11),('20201118',('20201119',18),('20201120',('20201123',56),('20201124',61),('20201125',('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,0) over(order by dates) as prevdiff
from @t
) as t
order by dates desc

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。