求用戶登錄流水表中的用戶連續登錄天數


有一個用戶登錄流水表結構如下:

create table hy_login_flow(
    id number(4,0) not null primary key,
    name nvarchar2(20) not null,
    logindate date not null)

這樣給它充值:

insert into hy_login_flow(id,name,logindate) values('1','A001',to_date('2020-01-01','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('2','A001',to_date('2020-01-02','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('11','A001',to_date('2020-01-03','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('3','A001',to_date('2020-01-05','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('4','A001',to_date('2020-01-06','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('5','B001',to_date('2020-01-01','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('6','B001',to_date('2020-01-02','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('7','B001',to_date('2020-01-05','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('8','C001',to_date('2020-01-01','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('9','C001',to_date('2020-01-02','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('10','D001',to_date('2020-01-07','yyyy-MM-dd'));

然后我們觀察這些記錄:

可以發現,A001用戶從2020-1-1~2020-1-3連續登錄了三天,從2020-01-05~2020-01-06連續登錄了兩天;

B001用戶從2020-1-1-2020-1-2連續登錄了兩天,在2020-01-05只登錄了一天;

C001用戶從2020-1-01~2020-01-02連續登錄了兩天;

D001用戶只在2020-01-07登錄了一天。

我們的任務是編寫sql把用戶連續登錄的天數找出來。

 

首先,我們按用戶分組,按登錄時間升序排列一下,因為不同用戶的記錄毫無關系。

 

觀察上表,我們可以發現,連續登錄的用戶,他的logindate減去seq是一個定數,這是解決問題的關鍵所在。

於是我們再查了一次:

多出的BasicDate列就是用logindate減去seq的差值,我們可以發現連續登錄的記錄,basicdate都是一樣的。

接下來就好辦了,按name和basicdate分組,求記錄數就可以了。

最終SQL:

select b.name,count(*) from
(select a.*,a.logindate-a.seq as basicdate from
  (select row_number() over (partition by name order by logindate) as seq,name,logindate from hy_login_flow) a) b
group by b.name,b.basicdate
order by b.name

查詢結果:

 

本文用到的全部SQL:

create table hy_login_flow(
    id number(4,0) not null primary key,
    name nvarchar2(20) not null,
    logindate date not null)
    
insert into hy_login_flow(id,name,logindate) values('1','A001',to_date('2020-01-01','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('2','A001',to_date('2020-01-02','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('11','A001',to_date('2020-01-03','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('3','A001',to_date('2020-01-05','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('4','A001',to_date('2020-01-06','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('5','B001',to_date('2020-01-01','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('6','B001',to_date('2020-01-02','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('7','B001',to_date('2020-01-05','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('8','C001',to_date('2020-01-01','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('9','C001',to_date('2020-01-02','yyyy-MM-dd'));
insert into hy_login_flow(id,name,logindate) values('10','D001',to_date('2020-01-07','yyyy-MM-dd'));

commit;

select * from hy_login_flow
    
select row_number() over (partition by name order by logindate) as seq,name,logindate from hy_login_flow

select a.*,a.logindate-a.seq as basicdate from
(select row_number() over (partition by name order by logindate) as seq,name,logindate from hy_login_flow) a


select b.name,count(*) from
(select a.*,a.logindate-a.seq as basicdate from
  (select row_number() over (partition by name order by logindate) as seq,name,logindate from hy_login_flow) a) b
group by b.name,b.basicdate
order by b.name

 

參考資料:

1.https://bbs.csdn.net/topics/396162708?page=1#post-411014646 引發問題的帖子。

2.https://blog.csdn.net/padluo/article/details/81113438  受啟發的文章,在此感謝作者無意中的指點。

--2020-03-19--


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM