计算每组的前 N 名

该博客讨论了如何在SQL和SPL中处理一个特定的查询问题,即获取股票大宗交易后三个交易日内的价格记录。由于交易日可能受到周末的影响,解决方案需要考虑日期逻辑和记录数量。文中提供了使用窗口函数的SQL解决方案以及使用SPL的更直观的方法,强调了SPL在处理此类有序计算时的便利性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【问题】

需求:

表 1 是股票发生大宗交易的股票代码、日期、大宗交易成交价格
表 2 是各个股票的历史记录

现在希望能够得到每个发生大宗交易的股票在这一天之后 3 天 (包括发生当天) 之内的价格记录

表 1 如下:

CodeDate1Price1  
12014/3/125  
22014/3/132  
32014/3/133  

表 2 如下:

CodeDate2Price2  
12014/3/104  
12014/3/114.09  
12014/3/124.01  
12014/3/134.05  
12014/3/144.10  
12014/3/154.50  
12014/3/164.45  
22014/3/104  
22014/3/114.09  
22014/3/124.01  
22014/3/134.05  
22014/3/144.10  
22014/3/154.50  
22014/3/164.45  
32014/3/104  
32014/3/114.09  
32014/3/124.01  
32014/3/134.05  
32014/3/144.10  
32014/3/154.50  
32014/3/164.45  
32014/3/174.50

得到的目标结果应该是:

CodeDate1Price1Date2Price2  
12014/3/1252014/3/124.01  
12014/3/1252014/3/134.05  
12014/3/1252014/3/144.10  
22014/3/1322014/3/134.05  
22014/3/1322014/3/144.10  
22014/3/1322014/3/154.50  
32014/3/1332014/3/134.05  
32014/3/1332014/3/144.10  
32014/3/1332014/3/154.50

最基本的连接我会写,但是要怎么限定在大宗交易发生之后 3 个交易日的记录不知道要怎么去限定。而且,因为交易存在双休日,是不能通过限定日期的,必须通过判断记录数才行。
求大神指导,跪谢!

【回答】

自然的思路是:关联两表后按 Code、Date1 和 Date2 排序,再按 Code 和 Date1 分组,取每组中 Date2 大于等于 Date1 的三条记录即可完成。但由于 SQL 分组后无法保存分组结果,而且 SQL 集合无序很难取出连续的三条记录。对于支持窗口函数的数据库实现要简单些:

select*  
from( select ROW_NUMBER() OVER( PARTITION by t1.code,t1.date1  ORDER BY t2.date2) rn,  
t1.code,  
t1.date1,  
t1.price1,  
t2.date2,  
t2.price2  
 from t1  
 join t2  on t1.code = t2.code  
 where t2.date2 >= t1.date1) t  
 where rn <= 3

这类有序计算使用 SPL 会更方便,有集合数据和按位置操作的功能,代码通用直观,也能适用于没有窗口函数的数据库:

A
1$(db1)select t1.code Code, t1.date1 Date1, t1.price1 Price1, t2.date2 Date2, t2.price2 Price2 from t0070_1 t1join t0070_2 t2 on t1.code = t2.code where t2.date2 >= t1.date1 order by t1.code,t1.date1,t2.date2
2=A1.group(Code,Date1).(~.m([1,2,3]).select(~)).conj()

关于更多 SPL 集合的使用,参考《SPL 中集合的使用

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值