当前位置: 首页 > news >正文

SQL CASE表达式与窗口函数

 CASE 表达式是一种通用的条件表达式,类似于其他编程语言中的if/else语句。

窗口函数类似于group by,但是不会改变记录行数,能扫描所有行,能对每一行执行聚合计算或其他复杂计算,并把结果填到每一行中。

1 CASE 表达式

CASE 表达式有简单CASE表达式和搜索CASE表达式两种写法:

-- 简单 CASE 表达式
CASE `status`WHEN 1 THEN '正常'WHEN 0 THEN '审核中'ELSE '锁定'
END-- 搜索CASE表达式
CASE WHEN `status` = 1 THEN '正常'WHEN `status` = 0 THEN '审核中'ELSE '锁定'
END  

  1.1 在SELECT 与 GROUP BY 中同时使用

图 城市人口信息表t_city_info

需求:根据上表,统计对应省份的人口数。

图 统计出的对应人口数

SELECT
CASE city 
WHEN '九江' THEN '江西'
WHEN '赣州' THEN '江西' 
WHEN '南昌' THEN '江西'
WHEN '深圳' THEN '广东'
WHEN '广州' THEN '广东'
WHEN '韶关' THEN '广东'
WHEN '惠州' THEN '广东'
ELSE '其他' 
END AS '省份',
SUM(population) AS '人口'
FROM t_city_info
GROUP BY
(
CASE city 
WHEN '九江' THEN '江西'
WHEN '赣州' THEN '江西' 
WHEN '南昌' THEN '江西'
WHEN '深圳' THEN '广东'
WHEN '广州' THEN '广东'
WHEN '韶关' THEN '广东'
WHEN '惠州' THEN '广东'
ELSE '其他' 
END 
)

1.2 在聚合函数内使用CASE表达式

图 表城市男女人口数量表t_city_info,1 表示男性 0 表示女性

 需求,根据上表统计出各市男女数量,输出格式如下:

图 各市男女数量

SELECT city as '城市',
SUM(
CASE sex 
WHEN 1 THEN population
ELSE 0
END
) AS '男性',
SUM(
CASE sex 
WHEN 0 THEN population
ELSE 0
END
) AS '女性'
FROM t_city_info
GROUP BY city

1.3 在update里使用CASE

图 员工薪资信息表t_emplpyee及薪资调整

需求:工资25000以上的降薪10%,10000以下的涨薪2000。

UPDATE t_employee 
SET salary = 
CASE WHEN salary > 25000 THEN salary * 0.9WHEN salary < 10000 THEN salary + 2000ELSE salary 
END

1.4 在CASE里使用嵌套子查询

图 课程信息表t_course_info 与 开课情况t_course_open表

需求:统计各课程每月开课情况。

图 各课程每月开课情况

SELECT 
`name` AS '课程',
(CASE WHEN EXISTS  (SELECT `course_id`FROM t_course_openWHERE `month` = '202408'	AND course_id = id ) THEN 'YES'ELSE 'no'END	 
) AS '8月',
(CASE WHEN EXISTS(SELECT `course_id`FROM t_course_openWHERE `month` = '202409'	AND course_id = id ) THEN 'YES'ELSE 'no'END	 
) AS '9月',
(CASE WHEN EXISTS (SELECT `course_id`FROM t_course_openWHERE `month` = '202410'	AND course_id = id ) THEN 'YES'ELSE 'no'END	 
) AS '10月'
FROM t_course_info

1.5 在CASE中使用聚合函数

图 学生加入俱乐部情况t_student_club 表

学生加入俱乐部情况:1)1个学生可以加入多个俱乐部;2)如果加入了多个俱乐部,Y标志主俱乐部,只加入一个俱乐部标注N。

需求:1)列出学生参加的主俱乐部。2)如果学生只假如一个俱乐部,则也为主俱乐部。

SELECT student_id AS '学生',
CASE WHEN COUNT(*) = 1 THEN club_nameELSE MAX(CASE WHEN main_flg = 'Y' THEN club_name ELSE NULL END) 
END AS '主俱乐部'
FROM t_student_club
GROUP BY student_id

2 窗口函数

窗口函数和聚合函数共同点在于它们也是对一组数据进行分析。但是窗口函数不是将一组数据汇总为单个结果,而是针对查询中的每一行数据,基于和它相关的一组数据计算出一个结果。语法如下:

window_fun (expr) over (

     partition by …

order by …

frame_clause

)

PARTITION BY 子句分隔记录集合,类似于group by

ORDER BY 子句对记录排序

frame_clause 串口大小,帧子句,定义以当前记录为中心的子集。

2.1 匿名窗口与命名窗口

图 服务器每日请求量t_service_load 表

需求:列出服务器每日请求量、前两日请求评价数。

SELECT `date`,`load`,
AVG(`load`) OVER (ORDER BY `date`ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
) AS avgLoad
FROM t_service_load;

2.1.1 命名窗口

SELECT `date`,`load`,
AVG(`load`) OVER loadW AS avgLoad,
SUM(`load`) OVER loadW AS sumLoad
FROM t_service_loadWINDOW loadW AS (ORDER BY `date`ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING
)

2.2 帧子句

ROWS

按行设置移动单位。

RANGE

按列值设置移动单位。使用ORDER BY 子句来指定基准列。

n PRECEDING

仅向前(行号较小的方向)移动n行。

n FOLLOWING

仅向后移动n行。

UNBOUNDED PRECEDING

一直移动到最前面。

UNBOUNDED FOLLOWING

一直移动到最后面。

CURRENT ROW

当前行。

表 帧子句中可以使用的选项

需求:统计上表中,两日前的请求量。

SELECT `date`,`load`,
MAX(`load`) OVER (ORDER BY `date` ASC RANGE BETWEEN INTERVAL 2 DAY PRECEDING AND INTERVAL 2 DAY PRECEDING
) AS preLoad
FROM t_service_load;
http://www.lryc.cn/news/476943.html

相关文章:

  • 基于SpringBoot的植物园管理小程序【附源码】
  • asp.net网站项目如何设置定时器,定时获取数据
  • 单元/集成测试解决方案
  • 高效作业跟踪:SpringBoot作业管理系统
  • keepalived + nginx 实现网站高可用性(HA)
  • 有哪些编辑器,怎样选择编辑器
  • 软件系统开发
  • 浅谈RPC的实现原理与RPC实战
  • 算法|牛客网华为机试31-40C++
  • Mysql 大表limit查询优化原理
  • 封装axios、环境变量、api解耦、解决跨域、全局组件注入
  • CDGP|数据治理于企业而言到底有什么用?
  • Java学习教程,从入门到精通,Java数组(Arrays)语法知识点及案例(19)
  • 11.4OpenCV_图像预处理习题02
  • go的template示例
  • 『YOLO』| 断点训练、解决训练中断异常情况
  • MQTT+Disruptor 提高物联网高并发
  • SpringBoot项目集成ONLYOFFICE
  • 用于nodejs的开源违禁词检测工具 JavaScript node-word-detection
  • FFmpeg 4.3 音视频-多路H265监控录放C++开发十二:在屏幕上显示多路视频播放,可以有不同的分辨率,格式和帧率。
  • Linux权限问题(账号切换,权限,粘滞位)
  • el-upload,上传文件,后端提示信息,前端需要再次重新上传(不用重新选择文件)
  • 数字信号处理Python示例(5)使用实指数函数仿真PN结二极管的正向特性
  • ctfshow(89,90,92,93)--PHP特性--intval函数
  • 构建ubuntu22.04.4私有源服务以及配置ubuntu私有源
  • 模块功能的描述方法
  • 【WPF】MatrixTransform类
  • 【C++】继承的理解
  • day50 图论章节刷题Part02(99.岛屿数量 深搜、99.岛屿数量 广搜、100.岛屿的最大面积)
  • 超详细从基准将VMware ESXi 升级到 vSphere 6.7U1教程