首页 > 数据库 >lag与lead函数 oracle_11g

lag与lead函数 oracle_11g

时间:2023-03-31 23:56:40浏览次数:42  
标签:11g TRAN CUS NO lag MONTH test2 oracle AMT

lag与lead函数 oracle_11g

lag与lead函数都可以实现跨行引用,语法如下:

lag( col [,n1] [,n2] ) over( [分区子句] 排序子句 )
lead( col [,n1] [,n2] ) over( [分区子句] 排序子句 )

语法注解:
参数:
	col,n1,n2
	
lag可以返回按排序子句排序后指定列的前n1行的值(如果不指定n1,则默认为1);
lead可以返回按排序子句排序后指定列的后n1行的值。如果不存在可以指定值n2,否则默认为空值null。
lag与lead函数中排序子句是必要的
--建表
create table test2(
  CUS_NO varchar2(10),    --客户编号
  TRAN_MONTH varchar2(6), --交易月份
  TRAN_AMT numeric(20,2)  --交易金额
);

--插入测试数据
insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101028','201910',1415.00);commit;
insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101028','201911',39.00);commit;
insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101028','201912',580.00);commit;
insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101028','202010',915.00);commit;
insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101028','202011',1200.00);commit;
insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101028','202012',800.00);commit;

insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101029','201910',540.00);commit;
insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101029','201911',495.00);commit;
insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101029','201912',360.00);commit;
insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101029','202001',990.00);commit;
insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101029','202011',190.00);commit;

insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101030','201910',990.00);commit;
insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101030','201911',330.00);commit;
insert into test2(CUS_NO,TRAN_MONTH,TRAN_AMT) values('cus_101030','202001',560.00);commit;

需求:统计每个客户月度消费的环比增长率,同比增长率

例:

月度消费环比增长率 =(当月消费金额-上月消费金额)/上月消费金额 ×100%

月度消费同比增长率 =(当月消费金额-去年同期消费金额)/去年同期消费金额 ×100%

为了计算环比、同比增长率,需要获取每个月对应的上个月、去年同期的消费金额

full join全连接

在执行完全外连接时,Oracle 会执行一个完整的左外连接和右外连接查询,然后将查询结果合并,并消除重复的记录行。


-- 补齐客户月度消费数据
SELECT 
	COALESCE( a.CUS_NO, b.CUS_NO ) AS 客户编号,
	COALESCE ( a.TRAN_MONTH, b.TRAN_MONTH ) AS 交易月份,
	a.TRAN_AMT 交易金额
FROM
	test2 a
	FULL JOIN (
		-- 内联接表 笛卡尔 客户编号+日期月份 排重
		SELECT DISTINCT
			b.CUS_NO,
			to_char ( a.date_list, 'YYYYMM' ) AS TRAN_MONTH 
		FROM (
				-- 给定日期开始根据日期天数生成日期
				SELECT
					to_date ( '20191001', 'YYYYMMDD' ) + rownum - 1 AS date_list 
				FROM
					DUAL 
					-- 生成数字序列结果集  日期天数
				connect BY rownum <= ( to_date ( '20201201', 'YYYYMMDD' ) - to_date ( '20191001', 'YYYYMMDD' ) ) + 1 
			) a, ( SELECT DISTINCT CUS_NO FROM test2 ) b 
	) b ON a.CUS_NO = b.CUS_NO 
	AND a.TRAN_MONTH = b.TRAN_MONTH;

-- 计算客户月度消费的环比、同比增长率
SELECT
	CUS_NO 客户编号,
	TRAN_MONTH 交易月份,
	TRAN_AMT 交易金额,
	lag ( TRAN_AMT, 1 ) over ( PARTITION BY CUS_NO ORDER BY TRAN_MONTH ) AS lag上个月, -- lag上个月
	lag ( TRAN_AMT, 12 ) over ( PARTITION BY CUS_NO ORDER BY TRAN_MONTH ) AS lag上一年同月, -- lag上一年同月
	lead ( TRAN_AMT, 1 ) over ( PARTITION BY CUS_NO ORDER BY TRAN_MONTH DESC ) AS lead上个月, -- lead上个月
	lead ( TRAN_AMT, 12 ) over ( PARTITION BY CUS_NO ORDER BY TRAN_MONTH DESC ) AS lead上一年同月 -- lead上一年同月 
FROM (
	SELECT 
		COALESCE( a.CUS_NO, b.CUS_NO ) AS CUS_NO,
		COALESCE ( a.TRAN_MONTH, b.TRAN_MONTH ) AS TRAN_MONTH,
		a.TRAN_AMT TRAN_AMT
	FROM
		test2 a
		FULL JOIN (
			-- 内联接表 笛卡尔 客户编号+日期月份 排重
			SELECT DISTINCT
				b.CUS_NO,
				to_char ( a.date_list, 'YYYYMM' ) AS TRAN_MONTH 
			FROM (
					-- 给定日期开始根据日期天数生成日期
					SELECT
						to_date ( '20191001', 'YYYYMMDD' ) + rownum - 1 AS date_list 
					FROM
						DUAL 
						-- 生成数字序列结果集  日期天数
					connect BY rownum <= ( to_date ( '20201201', 'YYYYMMDD' ) - to_date ( '20191001', 'YYYYMMDD' ) ) + 1 
				) a, ( SELECT DISTINCT CUS_NO FROM test2 ) b 
		) b ON a.CUS_NO = b.CUS_NO 
		AND a.TRAN_MONTH = b.TRAN_MONTH
	) test3;

上面代码中,

lag(TRAN_AMT,1) 表示在按客户编号分组并且按交易月份排序后,取当前行往前第1行,即当前月份的上月,如果往前第1行没有数据,则会置为空。

lag(TRAN_AMT,12) 表示取当前行往前第12行,即当前月份的去年同月。

lead的语用法和lag相反,上面代码排序子句中将TRAN_MONTH倒序排序后,lead取得的结果和lag一致。

标签:11g,TRAN,CUS,NO,lag,MONTH,test2,oracle,AMT
From: https://www.cnblogs.com/fuqian/p/17277893.html

相关文章

  • ORACLE数据库基础知识
    ORACLE数据库基础知识Oracle简介Oracle数据库系统是美国Oracle公司(甲骨文)提供的以分布式数据库为核心的一组软件产品,是目前最流行的客户/服务器(client/server)或B/S体系结构的数据库之一。Oracle数据库是目前世界上使用最为广泛的数据库管理系统,作为一个通用的数据库系统,它具......
  • 窗口函数 oracle_11g
    窗口函数oracle_11g数据库中的窗口函数也叫分析函数,顾名思义,窗口函数可用于一些复杂的统计分析计算,另外,窗口函数还具有优越的性能表现,可以节约时间和资源,因此窗口函数经常用于数据仓库和大型报表应用中。窗口函数的结构窗口函数由四部分组成,分别是分析函数名、分区子句、排......
  • oracle静默安装
    ##################       如何确定安装的oracle是否有问题?              #####################......
  • 对于11g新特性自适应游标共享
    绑定变量优缺点、使用、绑定变量窥探、Oracle自适应共享游标_ITPUB博客自适应游标共享虽然解决了一些由于10g中绑定变量窥探只进行首次硬解析才窥探生成执行计划,由于数据倾斜造成执行计划不准确问题,但是不是每次执行sql都进行窥探,游标共享是“自适应”的,也会出现执行计划不准确......
  • oracle的各版本的名称
    我最早接触的是oracle的版本8那个时候是8ii是internet后来是9i然后到10,就是版本10gg是grid的意思然后是11g然后12就变成了C,就是12cc是cloud的意思然后后面的版本是18c19c21c现在23c还处于研发阶段现在主推的版本是19c————————————————版权声明:本文为CSDN博主......
  • oracle 禁用job任务
    参考(17条消息)Oracle11g自带的系统Job介绍_oracle11gjob_shayuwei的博客-CSDN博客SQL>selectjob_namefromdba_scheduler_jobs;SQL>setlin160SQL>colownerfora10SQL>colDIRECTORY_NAMEfora25SQL>colDIRECTORY_PATHfora50SQL>select*fromd......
  • oracle锁表
    1.查询引起了锁表的原因SELECTl.session_idsid,s.serial#,l.locked_mode,l.oracle_username,s.user#,l.os_user_name,s.machine,s.terminal,a.sql_text,a.actionFROMv$sqlareaa,v$sessions,v......
  • oracle 查看表空间实际占用情况
    SELECTtablespace_name表空间名,round(SUM(bytes)/1000/1000/1000,2)alloc_bytes,round(SUM(maxbytes)/1000/1000/1000,2)maxbytesFROMdba_data_filesGROUPBYtablespace_name;SELECTtablespace_nam......
  • oracle 优化监控相关
    SELECTsn.username,m.SID,sn.SERIAL#,m.TYPE,DECODE(m.lmode,0,'None',1,'Null',2,'RowShare',3,'RowExcl.',4,......
  • Docker安装Oracle11g
    拉取镜像#拉取镜像dockerpullregistry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g#查看镜像dockerimages镜像比较大(6.9G),可能拉取时间会很久,需要耐心等待创建容器dockerrun-d-p1521:1521--nameoracleregistry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g#......