一、场景
1.1 问题
如下表、拿到数据的一部分,其中一月份缺少4日、9日、15日。
问题:如何知道连续n日的都有成交量的日期,用SQL语句写出来。
例子:n=3,1月1日就是目标日期,1月2日就不是目标日期。
1.2 环境
系统:win11
数据库:SQL Server2021
二、解题思路
2.1 循环判定
这是想到的第一个思路,这种思路主要是受Python的影响。
比如,n=3 我要判定1月1日是否是目标日期,我可以对1月1日至1月3日的日期都进行判定,如果都是True,则返回True,否则返回False。
可这是SQL ,所有的变量都要声明,循环写起来能够吐血。
可以成功,但绝非良策。
2.2 开窗函数
参考:https://www.cnblogs.com/qianslup/p/15113955.html
/* 如果n=3 保证每个日期,仅有一行数据,如果有两行或者两个以上的记录,则要先清洗数据。 按照日期顺排,取当前行后面n-1=2行的日期,再将两个日期比较,如果日期相差=2,则为目标日期,如果大于2增,不是目标日期 */ SELECT A.日期,A.交易量,[2行后的日期],CASE WHEN DATEDIFF(day,日期,[2行后的日期])=2 THEN '连续3天成交日期' else '未连续3天成交日期' end AS 判定 FROM ( SELECT *,MAX(日期) over (order by 日期 rows between current row and 2 following) as '2行后的日期' FROM test.cnblogs.连续 ) AS A order by 日期
-- 也可以使用关联的方法 select A.日期,A.交易量,B.日期 as [2行后的日期],CASE WHEN DATEDIFF(day,A.日期,B.日期)=2 THEN '连续3天成交日期' else '未连续3天成交日期' end AS 判定 from ( SELECT *,ROW_NUMBER() over (order by 日期) AS 顺序 FROM test.cnblogs.连续 ) as A LEFT JOIN ( SELECT *,ROW_NUMBER() over (order by 日期) as 顺序 FROM test.cnblogs.连续 ) as B ON A.顺序=B.顺序-2 ORDER BY a.日期
2.3 补充日期后开窗
/* 将缺失的日期补充进去, 保证从最小日期到最大日期,有且仅有一条数据。 */ declare @start_date date; declare @end_date date; set @start_date =(select min(日期) from test.cnblogs.连续 ) set @end_date =(select max(日期) from test.cnblogs.连续 ) while (@start_date < @end_date) begin while @start_date not in (select 日期 from test.cnblogs.连续) begin insert into test.cnblogs.连续 values(@start_date, 0) end set @start_date =DATEADD(day,1,@start_date) end SELECT *,case when 连续天数=3 THEN '连续3天成交日期' else '未连续3天成交日期' end AS 判定 FROM ( SELECT *,SUM(CASE WHEN 交易量>=1 then 1 else 0 end ) over (order by 日期 rows between current row and 2 following) as 连续天数 from test.cnblogs.连续 ) AS A
2.4 使用开窗函数的rang
失败了,思路是根据当前行的日期,到连续3天的日期,count(*)两个日期之间有多少条满足要求的数据。
比如1月1日,连续3天,就是1月3日,如果1月1日-1月3日之间有3条满足要求的记录,则为目标日期。
欢迎大佬指导。
标签:连续性,判断,end,cnblogs,test,日期,连续,date From: https://www.cnblogs.com/qianslup/p/17524396.html