Oracle开窗函数

目录

--常用的聚合开窗函数

--排名函数:

Oracle的ROW_NUMBER()连续登录问题,解决的思路

--平移函数:


--常用的聚合开窗函数

AVG(对哪个字段求平均值) OVER(PARTITION BY 分组字段 order by 字段)
MAX(对哪个字段求最大) OVER(PARTITION BY 分组字段 order by 字段)
MIN(对哪个字段求最小) OVER(PARTITION BY 分组字段 order by 字段)
SUM(对哪个字段求和) OVER(PARTITION BY 分组字段 order by 字段)
COUNT(对哪个字段进行计数) OVER(PARTITION BY 分组字段 order by 字段)

-- COUNT(*) 针对全表,将返回表格中所有存在的行,包括值为 NULL 的行
-- COUNT(1): 用1代表代码行,在统计结果中,不会忽略值为 NULL 的情况
-- COUNT(列名) : 统计该字段出现在表中的次数,忽略值为 NULL 的情况

-- 执行结果来说:
COUNT(*) 和 COUNT(1)没有区别,都不会过滤空值,但 COUNT(列名)会过滤空值


-- 执行效率来说:
(1) 如果你的列为主键,COUNT(列名),效率是优于 COUNT(1),如果不是,则相反
(2) 如果表中存在主键,COUNT(主键列名),效率最优,速度最快
(3) 如果表中只有一列,则 count(*) 效率 最优, 如果有多列且不存在主键, COUNT(1) 的 效率 要优于 COUNT(*);

-- 总结: 开窗函数和聚合函数的使用区别
1> 聚合函数的使用会有很多的限制,而开窗函数几乎没有(只要不写错单词)

2> 聚合函数分组使用的是 group by ,而开窗函数使用 partition by
3> 聚合函数是汇总出来的一个结果,而开窗函数会根据表中的行数,每一行返回一个结果


-- 开窗函数里面使用 ORDER BY 
1> 不仅有排序的功能,还有累计计算的作用(通过不能的字段来排序,累计的结果会改变)
2> 需求里面没有提到累计的时候,慎用开窗函数 over(order by )
3> 之前学的 ORDER BY 在整个语句中照常使用,执行顺序在最后,其全局排序作用

--排名函数:
  •  ROW_NUMBER(): 为每一行分配一个唯一的整数值,根据指定的排序规则进行排序  1 2 3 4
  •  RANK(): 为每一行分配一个排名值,相同排序值的行将获得相同的排名,并按照排名进行排序  1 1 3 4  
  •  DENSE_RANK(): 为每一行分配一个密集排名值,相同排序值的行将获得相同的排名,并按照排名进行排序 1 1 2 3
Oracle的ROW_NUMBER()连续登录问题,解决的思路

第一步:使用开窗函数 ROW_NUMBER(),根据需求,找出对应的字段进行分组,然后根据时间字段进行排序

第二步: 使用 时间字段 - 开窗函数的序列 
tips:
-- 1.2 -1 = 1.1
-- 1.3 -2 = 1.1
-- 1.4 -3 = 1.1
-- 如果是连续登录,所得到的时间结果值,必然是一样的

第三步: 根据 时间字段 - 开窗函数 row_number() 的序列 的值进行分组 ,并使用 COUNT(*) 进行计数 ,>1 的就是连续登录

WITH T1 AS
 (SELECT T.ID,
         T.AMOUNT,
         T.PAY_DATE,
         ROW_NUMBER() OVER(PARTITION BY T.ID ORDER BY T.PAY_DATE) RN,
         T.PAY_DATE - ROW_NUMBER() OVER(PARTITION BY T.ID ORDER BY T.PAY_DATE) LOGIN_DATE -- **
    FROM LX1112001 T)

SELECT T1.ID, T1.LOGIN_DATE, COUNT(*)
  FROM T1
 GROUP BY T1.ID, LOGIN_DATE
HAVING COUNT(*) > 2;

--平移函数:

LAG(X,Y,Z) -- 数据往上面偏移
X: 偏移哪个字段的数据 
Y:偏移多少行,如果没有输入偏移量,则默认为1行。
Z:当偏移找不到值,可以给一个默认的值

LEAD(X,Y,Z) -- 往数据下面偏移 
X: 偏移哪个字段的数据 
Y:偏移多少行,如果没有输入偏移量,则默认为1行。
Z:当偏移找不到值,可以给一个默认的值

解决同比,环比增长率问题

SELECT
YM,  -- 年份(月份)
AMT,  -- 销售额
round(  -- 四舍五入
(AMT-LAG(AMT,1,amt)OVER(ORDER BY YM))  -- 本月-上月
/ LAG(AMT,1) OVER (ORDER BY YM),2  -- 上月的销售额
) * 100 || '%' AS 增长率  -- 计算增长率并添加百分号
FROM SAL

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