Oracle数据间断累加

一.问

说明:当我们手里有一列数据(假设为时间数据),此时间数据是不规则间断的
要求:我们要计算此数据开始到间断之间的连续次数,如果间断,则重新开始计算下一个间断间的连续次数

二.解

  1. 首先,我们要计算出辅助列(contin/contin2):
select shift_date,

case when lag(shift_date,1,shift_date+1)over(order by shift_date)+1=shift_date 
then 
	(case when lead(shift_date,1,shift_date-1)over(order by shift_date)-1=shift_date 
	then null 
	else shift_date end) 
else shift_date end contin,

case when lead(shift_date,1,shift_date-1)over(order by shift_date)-1=shift_date 
then null 
else 'Y' end contin2 

from .....

在这里插入图片描述
如图,我们可以得到contin,这一列记录了间断的开始时间于结束时间,而中间的连续时间值为空,以及contin2,这一列则只在结束时间处加字符标记’Y’

  1. 我们将**contin **列为空的数据排除,并且将此列的上下两行数据相减
select contin-nvl(lag(contin,1,null)over(order by shift_date),contin) unit,contin,contin2 from
	(select shift_date,
	
	case when lag(shift_date,1,shift_date+1)over(order by shift_date)+1=shift_date 
	then 
		(case when lead(shift_date,1,shift_date-1)over(order by shift_date)-1=shift_date 
		then null 
		else shift_date end) 
	else shift_date end contin,
	
	case when lead(shift_date,1,shift_date-1)over(order by shift_date)-1=shift_date 
	then null 
	else 'Y' end contin2 
	
	from .....)
where contin is not null

在这里插入图片描述
如图,我们得到了unit这一列记录数据间间隔的值,

2.5.如果出现contin2值粘合现象,如图:
在这里插入图片描述
则使用如下代码来进行判断unit的值,基本逻辑为,当两个’Y’值为下上两行时,unit的值为0:

case when lag(contin2,1,null)over(order by usetname,shift_date) =contin2 and contin2='Y' 
then 0 
else contin-nvl(lag(contin,1,null)over(order by usetname,shift_date),contin)end unit

在这里插入图片描述
如过不出现则不做此判断,直接跳过,按正常逻辑来处理unit

3.我们只需要开始与结束时间的间隔,所以我们将contin2列为空的数据排除,因为要将开始的那一天也算,所以最后我们进行调整(持续时间天数+1)

select unit+1 unit,contin from	
	(select contin-nvl(lag(contin,1,null)over(order by shift_date),contin) unit,contin,contin2 from
		(select shift_date,
		
		case when lag(shift_date,1,shift_date+1)over(order by shift_date)+1=shift_date 
		then 
			(case when lead(shift_date,1,shift_date-1)over(order by shift_date)-1=shift_date 
			then null 
			else shift_date end) 
		else shift_date end contin,
		
		case when lead(shift_date,1,shift_date-1)over(order by shift_date)-1=shift_date 
		then null 
		else 'Y' end contin2 
		
		from .....)
	where contin is not null)
where contin2 ='Y' order by contin

在这里插入图片描述
如图,我们得到了结束时间与开始时间到结束时间的间断的累加数值

4.如果你觉得这样还不满足?想要开始时间与结束时间?

select contin-unit opening_time,contin end_time,unit+1 unit from
	(select contin-nvl(lag(contin,1,null)over(order by shift_date),contin)  unit,contin,contin2 from
		(select shift_date,
		
		case when lag(shift_date,1,shift_date+1)over(order by shift_date)+1=shift_date 
		then 
			(case when lead(shift_date,1,shift_date-1)over(order by shift_date)-1=shift_date 
			then null 
			else shift_date end) 
		else shift_date end contin,
		
		case when lead(shift_date,1,shift_date-1)over(order by shift_date)-1=shift_date 
		then null 
		else 'Y' end contin2 
		
		from .....)
	where contin is not null)
where contin2 ='Y' order by contin

在这里插入图片描述
5.如果要代入其他行列,如用户姓名,则将所有lead函数和lag的over()里添加

partition by user_name 

6.如果是多个用户,每个用户所持数据不一,而我们想看截止当天的持续时间,则:

and end_time=trunc(sysdate)

7.如果多个用户的部门不一,想要各个部门的数据整合,并且要得出每个状态的具体人数:示意代码

selelct 部门,
sum(case when unit>6 then 1 else 0 end)正常,
sum(case when unit<=5 and unit>=3 then 1 else 0 end)警告,
sum(case when unit <=2 then 1 else 0 end)异常
from(...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值