sql逻辑题07

需求:要取出按照时间轴顺序,发生了状态变化的数据行

其实不一定是状态,我们可以结合实际应用的一些场景想象一下,比如在玩网络游戏时都是有后台数据库的,数据库会后台会记录的一些后台数据来对玩家游戏是否在线状态 ,比如:上午10:00你在玩游戏,那么会被后台监控到在线状态10:00这个时间点你会是‘在线’状态,11:00你下线了,那么11:00这个时间点你在后台的状态就会被标识为‘离线’。下面的例子为电商中客户利率为例子,大家遇到实际的场景灵活运用,小编在这里抛砖引玉在网上摘抄个简单的例子。

数据准备:

--创建表
create table shopping(
id varchar(20),
rate varchar(20),
rq date
);

--插入数据
insert into shopping values
(100,0.1,'2021-03-02'),
(100,0.1,'2021-02-02'),
(100,0.2,'2021-03-05'),
(100,0.2,'2021-03-06'),
(100,0.3,'2021-03-07'),
(100,0.1,'2021-03-09'),
(100,0.1,'2021-03-10'),
(100,0.1,'2021-03-10'),
(200,0.1,'2021-03-10'),
(200,0.1,'2021-02-02'),
(200,0.2,'2021-03-05'),
(200,0.2,'2021-03-06'),
(200,0.3,'2021-03-07'),
(200,0.1,'2021-03-09'),
(200,0.1,'2021-03-10'),
(200,0.1,'2021-03-10');

这个题实际上还是比较简单的,假象一下假如你不用工具就单纯的用肉眼去比对这些数据的状态是否发生变化会有哪些流程,无非是先根据客户的时间先做下排序,然后基于同一个客户看这个客户的利率是否发生变化,如果变化那么这条数据就满足题目的要求。其实我们用sql也是一样的道理,只是通过sql内部的语言代替你的思路。

做这道题如果你知道以下两个函数,那么这道题是很简单的。

LAG语法:LAG([,offset[, default_value]]) OVER ( PARTITION BY expr,... ORDER BY expr [ASC|DESC],... )

LEAD语法:LEAD([,offset[, default_value]]) OVER ( PARTITION BY (expr) ORDER BY (expr))

lag可以基于当前数据获取这条数据之前的数据。

lead与lag相反正好是获取到这条数据之后的数据。

sql实现:

select id,rate,rq,rate_next from(
select id,rate,rq,lead(rate,1,0) over(partition by id order by rq) rate_next from shopping
)t1
where t1.rate <> t1.rate_next
and t1.rate_next<>0

注意细节:当然我们要排除掉rate_next等于0的这种情况。相当于状态的开始,状态开始的前一条数据是不存在的我们给他赋值为0,剔除掉即可。

实现结果:

sql逻辑题07_第1张图片

 

你可能感兴趣的:(sql,数据库)