SQL面试题:类递归计算

简介: 最近遇到一个比较有意思的SQL题,看似需要使用递归计算,其实不然,可以使用窗口函数解决

题目:有表t,数据如下

date_month

avg_views

2022-01

3621

2022-02

3786

2022-03

2685

2022-04

2433

2022-05

2241

2022-06

2756

2022-07

3589

2022-08

4215

2022-09

5894

需要计算:截止到当月,前月距离当月月数*签约views数累计之和,结果如下

date_month

avg_views

res

2022-01

3621

3621*1

2022-02

3786

3786*1+3621*2

2022-03

2685

2685*1+3786*2+3621*3

2022-04

2433

2433*1+2685*2+3786*3+3621*4

2022-05

2241

2241*1+2433*2+2685*3+3786*4+3621*5

2022-06

2756

2756*1+2241*2+2433*3+2685*4+3786*5+3621*6

2022-07

3589

3589*1+2756*2+2241*3+2433*4+2685*5+3786*6+3621*7

2022-08

4215

4215*1+3589*2+2756*3+2241*4+2433*5+2685*6+3786*7+3621*8

2022-09

5894

5894*1+4215*2+3589*3+2756*4+2241*5+2433*6+2685*7+3786*8+3621*9

看着有点像乘法口诀表哈,在这里做一下题目需求的解释:

1.截止到2022-01月:只有3621,距离本月为1个月,即3621*1;

2.截止到2022-02月:1月距离本月为2个月,即1月的36213621*2,2月距离本月为1,即3786,求和为3621*2+3786;

以此类推计算截止到每个月的前月累计。


我们只看1月的数值在res列均出现了,相当于直接sum的,这里就可以想到使用sum over开窗函数累加数据

select  date_month,  avg_views,  sum(avg_views) over(orderby date_month) res1
from t

得到的结果如下

date_month

avg_views

res1

2022-01

3621

3621*1

2022-02

3786

3786*1+3621*1

2022-03

2685

2685*1+3786*1+3621*1

2022-04

2433

2433*1+2685*1+3786*1+3621*1

2022-05

2241

2241*1+2433*1+2685*1+3786*1+3621*1

2022-06

2756

2756*1+2241*1+2433*1+2685*1+3786*1+3621*1

2022-07

3589

3589*1+2756*1+2241*1+2433*1+2685*1+3786*1+3621*1

2022-08

4215

4215*1+3589*1+2756*1+2241*1+2433*1+2685*1+3786*1+3621*1

2022-09

5894

5894*1+4215*1+3589*1+2756*1+2241*1+2433*1+2685*1+3786*1+3621*1

但这个结果好像和预期不一样,如果把res1结果在累加一次,应该会达到预期效果

select  date_month,  avg_views,  sum(res1) over(orderby date_month) res
from(select    date_month,    avg_views,    sum(avg_views) over(orderby date_month) res1
from t
) tmp

得到的结果如下,达到了预期效果,其实好像和递归也没啥关系,不知题意为何归为递归

date_month

avg_views

res

2022-01

3621

3621*1

2022-02

3786

3786*1+3621*2

2022-03

2685

2685*1+3786*2+3621*3

2022-04

2433

2433*1+2685*2+3786*3+3621*4

2022-05

2241

2241*1+2433*2+2685*3+3786*4+3621*5

2022-06

2756

2756*1+2241*2+2433*3+2685*4+3786*5+3621*6

2022-07

3589

3589*1+2756*2+2241*3+2433*4+2685*5+3786*6+3621*7

2022-08

4215

4215*1+3589*2+2756*3+2241*4+2433*5+2685*6+3786*7+3621*8

2022-09

5894

5894*1+4215*2+3589*3+2756*4+2241*5+2433*6+2685*7+3786*8+3621*9

今日解析SQL到此为止

拜了个拜

目录
相关文章
|
5月前
|
安全 Java 容器
【Java集合类面试二十七】、谈谈CopyOnWriteArrayList的原理
CopyOnWriteArrayList是一种线程安全的ArrayList,通过在写操作时复制新数组来保证线程安全,适用于读多写少的场景,但可能因内存占用和无法保证实时性而有性能问题。
|
5月前
|
存储 安全 Java
【Java集合类面试二十五】、有哪些线程安全的List?
线程安全的List包括Vector、Collections.SynchronizedList和CopyOnWriteArrayList,其中CopyOnWriteArrayList通过复制底层数组实现写操作,提供了最优的线程安全性能。
|
5月前
|
Java
【Java集合类面试二十八】、说一说TreeSet和HashSet的区别
HashSet基于哈希表实现,无序且可以有一个null元素;TreeSet基于红黑树实现,支持排序,不允许null元素。
|
5月前
|
Java
【Java集合类面试二十三】、List和Set有什么区别?
List和Set的主要区别在于List是一个有序且允许元素重复的集合,而Set是一个无序且元素不重复的集合。
|
5月前
|
Java
【Java集合类面试二十六】、介绍一下ArrayList的数据结构?
ArrayList是基于可动态扩展的数组实现的,支持快速随机访问,但在插入和删除操作时可能需要数组复制而性能较差。
|
5月前
|
存储 Java 索引
【Java集合类面试二十四】、ArrayList和LinkedList有什么区别?
ArrayList基于动态数组实现,支持快速随机访问;LinkedList基于双向链表实现,插入和删除操作更高效,但占用更多内存。
|
2月前
|
SQL 缓存 监控
大厂面试高频:4 大性能优化策略(数据库、SQL、JVM等)
本文详细解析了数据库、缓存、异步处理和Web性能优化四大策略,系统性能优化必知必备,大厂面试高频。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:4 大性能优化策略(数据库、SQL、JVM等)
|
2月前
|
SQL 存储 BI
gbase 8a 数据库 SQL合并类优化——不同数据统计周期合并为一条SQL语句
gbase 8a 数据库 SQL合并类优化——不同数据统计周期合并为一条SQL语句
|
2月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
137 4
|
4月前
|
安全 Java 应用服务中间件
JVM常见面试题(三):类加载器,双亲委派模型,类装载的执行过程
什么是类加载器,类加载器有哪些;什么是双亲委派模型,JVM为什么采用双亲委派机制,打破双亲委派机制;类装载的执行过程
109 35
JVM常见面试题(三):类加载器,双亲委派模型,类装载的执行过程