判断连续性

发布时间 2023-07-03 22:58:25作者: qsl_你猜

一、场景

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条满足要求的记录,则为目标日期。

欢迎大佬指导。