SQL-DAY 8(SQL窗口函数的应用案例:电商平台订单信息案例分析)

2023-11-13


一、窗口函数说明

1.窗口函数的语句结构

  • 窗口函数的语法格式
函数名 ([expr]) over(子句)

函数名 ([expr]) over( partition by <要分列的组> order by <要排序的列> rows between <数据范围>)

其中over关键字后子句包含三个分析子句
 分组子句partition by
 排序子句order by
 窗口子句rows

sum A over (partition by B order by C rows between D1 and D2)
avg A over(partition by B order by C rows between D1 and D2)
  • rows子句的相关示例
rows between 2 preceding and current row # 取当前行和前面两行

rows between unbounded preceding and current row # 包括本行和之前所有的行

rows between current row and unbounded following # 包括本行和之后所有的行

rows between 3 preceding and 1 following # 取前面三行和下面一行,包含当前行,总共五行

注意:
  当order by后面缺少窗口从句条件,窗口规范默认是rows between unbounded preceding and current row.
  当order by和窗口从句都缺失, 窗口规范默认是 rows between unbounded preceding and unbounded following

2.窗口函数的分类

  • 窗口函数分为两种
专用窗口函数 聚合类窗口函数
rank() 并列排名会跳号 sum()
dense_rank() 并列排名不会跳号 count()
row_number() 生成行的编号 avg()
max()
min()

二、案例分析(电商平台订单信息)

1.数据准备

表结构

列名 释义
user_name 用户名
piece 购买数量
price 价格
pay_amount 支付金额
goods_category 商品品类
pay_time 支付日期

建表语句

use lagou;
create table user_trade (
	user_name varchar(20),
	piece int,
	price double,
	pay_amount double,
	goods_category varchar(20),
	pay_time date
);

2.窗口函数之累计计算函数

需求1: 查询出2019年每月的支付总额和当年累积支付总额

-- step1 过滤出2019年数据
select * from user_trade where year(pay_time)=2019;

-- step2 在1的基础上,按照月份进行group by 分组,统计每个月份的支付总额
select month(pay_time),sum(pay_amount)
from user_trade
where year(pay_time) = 2019
group by month(pay_time);

-- step3 在2的基础上应用窗口函数实现需求
select a.month,a.pay_amount,
	sum(a.pay_amount) over (order by a.month) 
from(
	select month(pay_time) month,sum(pay_amount) pay_amount
	from user_trade
	where year(pay_time) = 2019
	group by month(pay_time)
) a;

需求2: 查询出2018-2019年每月的支付总额和当年累积支付总额

-- step1 过滤出2018-2019年数据
select * from user_trade where year(pay_time) in(2018,2019);

-- step2 在1的基础上,按照月份进行group by 分组,统计每个月份的支付总额
select year(pay_time),month(pay_time),sum(pay_amount)
from user_trade
where year(pay_time) in(2018,2019)
group by year(pay_time),month(pay_time);

-- step3 在2的基础上应用窗口函数实现需求
select a.year,a.month,a.pay_amount,
	sum(a.pay_amount) over (partition by a.year order by a.month) #基于年份进行了分组
from(
	select year(pay_time) year,month(pay_time) month,sum(pay_amount) pay_amount
	from user_trade
	where year(pay_time) in(2018,2019)
	group by year(pay_time),month(pay_time)
) a;

需求3: 查询出2019年每月的近三个月的移动平均支付金额

#操作rows窗口范围
select a.month,a.pay_amount,
	avg(a.pay_amount) over (order by a.month,rows between 2 preceding and current row) avg_pay_amount
from(
	select month(pay_time) month,sum(pay_amount) pay_amount
	from user_trade
	where year(pay_time) = 2019
	group by month(pay_time)
) a;

需求4: 查询出每4个月的最大月总支付金额

#操作rows窗口范围
select a.month,a.pay_amount,
	max(a.pay_amount) over (order by a.month,rows between 3 preceding and current row) max_pay_amount
from(
	select substring(pay_time,1,7) month,sum(pay_amount) pay_amount
	from user_trade
	group by substring(pay_time,1,7)
) a;

3.窗口函数之排序函数

需求1: 2020年1月,购买商品品类数的用户排名

select user_name,count(distinct(goods_category)) category_count,
	dense_rank() over (order by count(distinct(goods_category))) order1
from user_trade
where substring(pay_time,1,7) = '2020-01'
group by user_name;

需求2: 2020年2月的支付用户,按照支付金额分为5组后的结果

select user_name,sum(pay_amount),
	ntile(5) over (order by sum(pay_amount) desc) level
from user_trade
where substring(pay_time,1,7) = '2020-02'
group by user_name;

需求3: 查询出2020年支付金额排名前30%的所有用户

select a.user_name,a.pay_amount,a.level
from (
	select user_name,sum(pay_amount),
		ntile(10) over (order by sum(pay_amount) desc) level
	from user_trade
	where year(pay_time) = 2020
	group by user_name
) a
where a.level in(1,2,3);

3.窗口函数之偏移分析函数

需求1:解释lag(),lead()用法

select user_name,pay_time,
	lag(pay_time,1,pay_time) over (partition by user_name order by pay_time) lag1,
	lag(pay_time) lag0,
	lag(pay_time,1) lag2
from user_trade
where user_name in ('King','West');

注:lag(pay_time,1,pay_time)为向上偏移量,其中第一个pay_time为需要偏移的字段,1为偏移量,第二个pay_time为默认值,有默认值时,取不到偏移量,则显示为它本身;没有默认值时,取不到偏移量,则显示为null
   lead()为向下偏移量,其中1为偏移量

需求2:查询出支付时间间隔超过100天的用户数

select count(distinct(user_name))
from(
	select user_name,pay_time,
		lead(pay_time,1) over (partition by user_name order by pay_time) lead_time,
	from user_trade
	where user_name in ('King','West')
) a
where datediff(a.lead_time,a.pay_time) > 100;

需求2:查询出每年支付时间间隔最长的用户

#step1,算出时间间隔
select a.years,a.user_name,
	datediff(a.pay_time,a.lag_time)  interval_days
from(
#把相邻订单的pay_time放置到一行,便于后期求两个订单之间的间隔(按年和用户名进行分组)
#相邻订单中的一个订单的pay_time移动了下来成为了新的一列(当前订单pay_time-lag_timeX)
	select user_name,pay_time,year(pay_time) as years
		lag(pay_time) over (partition by user_name,year(pay_time) order by pay_time asc) lag_time,
	from user_trade
) a;

#step2,查询出每年支付时间间隔最长的用户
select b.years,b.user_name,b.interval_days
		
from(		
	select a.years,a.user_name,
		datediff(a.pay_time,a.lag_time) interval_days,
		rank() over(partition by a.years order by datediff(a.pay_time,a.lag_time) desc) rank
	from(
	#把相邻订单的pay_time放置到一行,便于后期求两个订单之间的间隔(按年和用户名进行分组)
	#相邻订单中的一个订单的pay_time移动了下来成为了新的一列(当前订单pay_time-lag_timeX)
		select user_name,pay_time,year(pay_time) as years
			lag(pay_time) over (partition by user_name,year(pay_time) order by pay_time asc) lag_time,
		from user_trade
	) a
) b
where b.rank1=1;

附上源数据供大家练习
电商平台订单信息案例分析源数据

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQL-DAY 8(SQL窗口函数的应用案例:电商平台订单信息案例分析) 的相关文章

  • 如何在 DB2 AS/400 中将小数字段转换为日期字段?

    我有一个 DECIMAL 字段 其中包含 AS400 格式的日期 1100614 我努力了 cast MYDATE as DATE 但我无法将 DECIMAL 转换为 DATE 而 DATE MYDATE 返回空值 如何将此字段转换为日期字
  • WordPress:wpdb->插入与wpdb->准备(wpdb->查询(“INSERT

    我想知道 WordPress 的插入功能是否也向数据添加斜杠 如果没有 准备查询方法似乎可以更好地防止 SQL 注入 我尝试在 codex api 中查找问题 然而 它似乎没有记录 谢谢 这个问题有点老了 自从提出这个问题以来 法典可能已经
  • 有没有办法阻止 SQL Express 2008 空闲?

    我使用 SQL Express 2008 作为 Web 应用程序的后端 问题是 Web 应用程序是在工作时间使用的 因此有时在午餐或休息时间 如果 20 分钟内没有用户登录 SQL Express 将进入空闲状态模式并释放其缓存 我知道这一
  • 只获取倒数第二条记录 - mysql-query

    我有一个如下表记录 my table id rating description 1 0 0 bed 2 1 0 good 3 0 0 bed 4 1 0 good 5 0 0 bed 6 0 0 bed 7 0 0 bed 现在我通过评级
  • 检查两个“select”是否相等

    有没有办法检查两个 非平凡的 选择是否等效 最初我希望两个选择之间有形式上的等价 但是答案在证明 sql 查询等价性 https stackoverflow com questions 56895 proving sql query equ
  • 在 Hibernate 中创建 UPDATE RETURNING 查询

    在 Oracle 中 我们可以创建一个更新查询 该查询将使用 RETURNING 子句返回更新的记录 Hibernate中有类似的功能吗 除了数据库生成的值之外 Hibernate 显然不需要返回更新的实例 因为对象传递给Session s
  • Android Realm.io:行/对象不再有效

    这是我的删除功能 它确实找到了workday1 object public static void delete Context context Workday workday Realm realm getRealm context re
  • Reporting Services 在哪里存储其日志文件

    最相关的谷歌结果似乎表明 为了访问日志 我们必须将您自己的日志表部署到数据库并制作报告服务写入它 http technet microsoft com en us library ms157403 aspx 简而言之 Reporting S
  • 我应该用不可变或可变的数据结构来表示数据库数据吗?

    我目前正在使用 Scala 进行编程 但我想这适用于任何函数式编程语言 或者更确切地说 任何建议不变性并可以与数据库交互的编程语言 当我从数据库中获取数据时 我将其映射到模型数据结构 在函数式编程中 数据结构往往是不可变的 但是数据库中的数
  • 如何搜索例程的内容/(SP-触发函数)

    我需要在数据库内所有例程的例程主体 存储过程 函数 触发器 中搜索文本 我该怎么做 Thanks SELECT OBJECT NAME object id FROM sys sql modules WHERE definition LIKE
  • 数据库字段中的逗号分隔值

    我有一个产品表 该表中的每一行对应一个产品 并由唯一的 ID 标识 现在 每个产品都可以有多个与该产品关联的 代码 例如 Id Code 0001 IN ON ME OH 0002 ON VI AC ZO 0003 QA PS OO ME
  • 如何在MYSQL中将整个字符串小写并保持第一个大写[重复]

    这个问题在这里已经有答案了 我的表栏目 我预期的输出会在列中发生变化 Smith Allen Doyle Dennis Baker Waker 这是我尝试过的 但不起作用 UPDATE TABLE employee SET last nam
  • 如何在 DB2 中创建返回序列值的函数?

    如何在 DB2 中创建一个从序列中获取值并返回该值的函数 应该可以在 select 或 insert 语句中使用该函数 例如 select my func from xxx insert into xxx values my func 基本
  • 删除数据库中的行后如何重新排序ID

    我正在使用 C 来制作具有 sql 数据库的程序 在数据库中我有一个名为Workers 它有一个自动增量和主键ID column 当我删除一条记录时 ID 之间会出现间隙 删除记录后如何重新排序 ID UPDATE 我要做的就是找到记录后将
  • 我不断收到错误“关系 [TABLE] 不存在”

    我一直在尝试查询数据库中的两个表 在服务器资源管理器中 我可以看到两个表 甚至可以看到其中的列 我们将它们称为 Schema table1 和 Schema table2 其中 Schema 的第一个字母大写 我尝试运行以下查询 selec
  • 无法在 Sqlite3 中添加默认值为 NULL 的 NOT NULL 列

    尝试将 NOT NULL 列添加到现有表时出现以下错误 为什么会发生这种情况 我尝试了 rake db reset 认为现有记录是问题所在 但即使重置数据库后 问题仍然存在 你能帮我解决这个问题吗 迁移文件 class AddDivisio
  • Spark SQL 中的 SQL LIKE

    我正在尝试使用 LIKE 条件在 Spark SQL 中实现联接 我正在执行连接的行看起来像这样 称为 修订 Table A 8NXDPVAE Table B 4 8 NXD V 在 SQL Server 上执行联接 A revision
  • 在 DataView 的 RowFilter 中选择 DISTINCT

    我试图根据与另一个表的关系缩小 DataView 中的行范围 我使用的 RowFilter 如下 dv new DataView myDS myTable id IN SELECT DISTINCT parentID FROM myOthe
  • Flutter 中有预填充数据库使用的示例吗?

    Flutter 中有预填充数据库使用的示例吗 我不需要 CRUD 示例 此时我只需要从数据库读取数据即可 我是 Flutter 新手 所以一步一步的教程会很好 您可以将您的应用程序与预填充的 sqlite 数据库捆绑在一起assets文件夹
  • 如何部署“SQL Server Express + EF”应用程序

    这是我第一次部署使用 SQL Server Express 数据库的应用程序 我首先使用实体 框架模型来联系数据库 我使用 Install Shield 创建了一个安装向导来安装应用程序 这些是我在目标计算机中安装应用程序所执行的步骤 安装

随机推荐

  • MATLAB实现多分类预测结果混淆矩阵(Confusion matrix)可视化

    对于多分类问题 如何对预测结果进行可视化分析是性能对比的关键 在实际多分类问题 除了简单展示模型预测精度外 如何理解不同类别之间的预测结果对于分析样本相关性和属性区别具有重要意义 在MATLAB中一般通过混淆矩阵confusion matr
  • Uber和它的规则&算法

    私以为 Uber这家公司的出现 标志着 科技重构资源的时代正式来临 这才是大数据真正的使命啊 enjoy 这个改变 以下信息来源 网络上流传的中文Uber解读 Uber的算法 均可以随着数据量的不断增加进行学习 所以只会越来越准 只会越来越
  • MySQL将一张表的数据copy到另一张表中

    1 复制旧表的数据到新表 假设两个表结构一样 INSERT INTO 新表 SELECT FROM 旧表 INSERT INTO tbl user copy SELECT FROM tbl user 2 复制表结构及数据到新表 CREATE
  • Keil不能正确生成.bin文件的解决办法

    1 打开keil IDE 然后打开help gt uVison Help 搜索fromelf关键字如下图1 然后再进入到右下角的索引找到fromelf命令行的语法和选项 找到 bin的说明如下 如红色标注所说 正是症结所在 即如果链接文件中
  • 安装ubuntu20.04(安装vim、gcc、VMtools、中文输入法、汉化、修改IP、无法连网问题)

    目录 ubuntu安装包获取 ubuntu的安装 安装网络配置命令ifconfig 连接网络 解决ubuntu无法连网问题 如何修改IP地址 安装VMtools 解决VMware Tools选项灰色 VMtools安装 安装中文 汉化 添加
  • 时间序列预测——GRU

    本文展示了使用GRU进行时间序列预测的全过程 包含详细的注释 整个过程主要包括 数据导入 数据清洗 结构转化 建立GRU模型 训练模型 包括动态调整学习率和earlystopping的设置 预测 结果展示 误差评估等完整的时间序列预测流程
  • 针对序列级和词元级应用微调BERT(需修改)

    对于序列级和词元级自然语言处理应用 BERT只需要最小的架构改变 额外的全连接层 如单个文本分类 例如 情感分析和测试语言可接受性 文本对分类或回归 例如 自然语言推断和语义文本相似性 文本标记 例如 词性标记 和问答 在下游应用的监督学习
  • 7-22龟兔赛跑/PTA基础编程题目集

    7 22 龟兔赛跑 20分 乌龟与兔子进行赛跑 跑场是一个矩型跑道 跑道边可以随地进行休息 乌龟每分钟可以前进3米 兔子每分钟前进9米 兔子嫌乌龟跑得慢 觉得肯定能跑赢乌龟 于是 每跑10分钟回头看一下乌龟 若发现自己超过乌龟 就在路边休息
  • 高效的学习方法

    背景 自己在复习自己专业课33页知识点时一筹莫展 死记硬背又记不住 背了上一个再背下一个上一个就忘记了 在复习的时候特别痛苦 而且定义性质的还是不能有错别字的 所以感觉自己背的特别痛苦 而且背完就忘 就像在做无用功 自己也想过用思维导图三遍
  • c++智能指针(一)

    C 智能指针 一 c 中的动态内存的管理是通过一对运算符来管理的 new 在动态内存中为对象分 配空间并返回一个指向该对象的指针 我们可以选择对对象进行初始化 delete 接受一个对象的指针 销毁对象 并且释放与之关联的内存 动态内存的使
  • oracle自动增加表空间指定分区

    Create table create table testTable tjsj DATE not null tablespace tablespace1 PARTITION BY RANGE TJSJ INTERVAL NUMTODSIN
  • spring boot(8)-mybatis三种动态sql

    脚本sql XML配置方式的动态SQL我就不讲了 有兴趣可以自己了解 下面是用
  • Qt之QChart各个图表的简单使用(含源码+注释)

    文章目录 一 图表操作示例图 1 图表选择示例 2 动画选项操作 3 图例选项操作 4 其他选项操作 二 QChart 个人理解 三 部分源码讲解 ui中添加动态属性 按钮组的使用 四 源码 CChartTest h CChartTest
  • [1106]python bezier(贝塞尔)曲线

    文章目录 三阶贝塞尔曲线 python bezier曲线 首先简单了解一下什么是贝塞尔曲线 余弦函数曲线我就不多说了哈 贝塞尔曲线又称贝兹曲线 是法国工程师皮埃尔 贝塞尔于1962年发表 贝塞尔曲线广泛应用于二维绘图软件 早期用于汽车车体设
  • 软件测试中单元测试,集成测试,系统测试,验收测试的区别

    软件测试按照研发阶段一般分为5个部分 单元测试 集成测试 确认测试 系统测试 验收测试 下面将不同阶段需要的一些工作内容做一下梳理希望可以帮助到大家 单元测试 是指对软件中的最小可测试单元进行检查和验证 测试方法 白盒测试 单元测试又称为模
  • Vue一键复制功能

    div class item2 2 span 复制 span div copy content let input document createElement input input value content input id crea
  • JavaScript实现搜索功能

    JavaScript实现搜索功能 实现效果 代码如下
  • npm install 卡在了 reify:rxjs: timing reifyNode,出现 gyp ERR find Python、gyp ERR find VS

    前言 最近跑一个vue的项目 第一步肯定是npm install 结果就出现我标题上写的那些情况 经过一番搜索 网上一堆方法尝试了 有说叫你用管理员权限运行 npm install global production windows bui
  • [NISACTF 2022]babyupload

    NISACTF 2022 babyupload 本题考点 python代码审计 os path join 处理路径拼接的问题 做题过程 经典的文件上传页面 F12查看源码
  • SQL-DAY 8(SQL窗口函数的应用案例:电商平台订单信息案例分析)

    文章目录 一 窗口函数说明 1 窗口函数的语句结构 2 窗口函数的分类 二 案例分析 电商平台订单信息 1 数据准备 2 窗口函数之累计计算函数 3 窗口函数之排序函数 3 窗口函数之偏移分析函数 一 窗口函数说明 1 窗口函数的语句结构