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

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.9
	 WHEN salary < 10000 THEN salary + 2000
	 ELSE salary 
END

1.4 在CASE里使用嵌套子查询

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

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

图 各课程每月开课情况

SELECT 
`name` AS '课程',
(
	CASE 
		 WHEN EXISTS  
				(SELECT `course_id`
				 FROM t_course_open
				 WHERE `month` = '202408'	AND course_id = id 
				) 
		 THEN 'YES'
		 ELSE 'no'
	END	 
) AS '8月',
(
	CASE 
		 WHEN EXISTS
				(SELECT `course_id`
				 FROM t_course_open
				 WHERE `month` = '202409'	AND course_id = id 
				) 
		 THEN 'YES'
		 ELSE 'no'
	END	 
) AS '9月',
(
	CASE 
		 WHEN EXISTS 
				(SELECT `course_id`
				 FROM t_course_open
				 WHERE `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_name
	ELSE 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_load

WINDOW 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.kler.cn/a/380409.html

相关文章:

  • mysql 查看数据库、表的基本命令
  • qt QMenuBar详解
  • WPF+MVVM案例实战(二十一)- 制作一个侧边弹窗栏(AB类)
  • 智能网联汽车:人工智能与汽车行业的深度融合
  • YOLOv11改进策略【卷积层】| CGblock 内容引导网络 利用不同层次信息,提高多类别分类能力 (含二次创新)
  • Session条件竞争--理论
  • Unity 中winform端转webGL异常处理
  • 100种算法【Python版】第43篇——优化算法之模拟退火算法
  • OpenCV视觉分析之目标跟踪(9)计算扩展相关系数computeECC()的使用
  • 【C语言】C程序的编译+链接
  • 机场电子采购信息系统
  • APScheduler:强大的Python定时任务调度器
  • Flutter鸿蒙next中的按钮封装:自定义样式与交互
  • AI绘画大热门!用AI做副业兼职3个月赚了10w,想辞职了
  • stl_list
  • 利用蒙特卡洛方法求定积分
  • Redis 初学者指南
  • 论文阅读-用于图像识别的深度残差学习
  • 应用targetsdk版本低于30,不符合华为应用市场审核标准
  • 【学习】软件测试中V模型、W模型、螺旋模型三者介绍
  • Docker Compose部署XXL-JOB
  • STM32实现串口接收不定长数据
  • 【专题】基于服务的体系结构
  • JS实现漂亮的登录页面(氛围感页面)
  • 【linux 多进程并发】0203 网络资源的多进程处理,子进程完全继承网络套接字,避免“惊群”问题
  • TypeScript实用笔记(三):泛型<T>的使用 <T>的12种工具类型的使用