(课堂笔记)Oracle:场景判断(CASE WHEN)、集合运算、EXISTS、行列转换
2026/4/28 18:43:15 网站建设 项目流程

这篇SQL课堂笔记总结了多种数据查询和处理的核心技术。


主要内容包括:

1)条件判断的CASE WHEN和DECODE语法及应用场景;

2)集合运算(UNION、INTERSECT等)的使用要点;

3)EXISTS子查询的高效实现方式;

4)行列转换的多种实现方法(CASE WHEN、DECODE、PIVOT)。


笔记通过具体示例演示了薪资分段、部门统计、成绩表转换等典型场景,并对比了不同技术的适用情况,如EXISTS与IN的效率差异。


最后还提供了员工分类统计等练习题,帮助巩固知识点。


以下是根据你提供的课堂内容整理的结构化复习笔记,涵盖了CASE WHENDECODE、集合运算、EXISTS、行列转换等核心知识点,便于学生快速回顾与理解。


📚 SQL 课堂笔记


一、场景判断:CASE WHEN ... END

语法结构

sql

CASE WHEN 条件1 THEN 返回值1 WHEN 条件2 THEN 返回值2 ... ELSE 默认值 END
  • 如果没有ELSE,默认返回NULL

  • 整个CASE WHEN ... END可视为一个字段

示例1:岗位汉化

sql

SELECT ENAME, JOB, CASE WHEN JOB = 'SALESMAN' THEN '销售' WHEN JOB = 'MANAGER' THEN '经理' WHEN JOB = 'CLERK' THEN '文员' ELSE '职员' END AS NEW_JOB FROM EMP;

示例2:按部门薪资分三段

sql

SELECT K.*, CASE WHEN NT = 1 THEN 'high_sal' WHEN NT = 2 THEN 'mid_sal' ELSE 'low_sal' END AS 薪资标签 FROM ( SELECT E.*, NTILE(3) OVER (PARTITION BY DEPTNO ORDER BY SAL DESC) AS NT FROM EMP E ) K;

示例3:部门人数标签

sql

SELECT DEPTNO, CNT, CASE WHEN CNT > 5 THEN '很多人' WHEN CNT > 3 AND CNT <= 5 THEN '人不多' END AS 人数标签 FROM ( SELECT DEPTNO, COUNT(1) AS CNT FROM EMP GROUP BY DEPTNO );

示例4:条件薪资调整

sql

SELECT DEPTNO, SUM(CASE WHEN DEPTNO = 10 THEN SAL + 1000 WHEN DEPTNO = 20 THEN SAL + 500 ELSE SAL END) AS NEW_TOTAL_SAL FROM EMP GROUP BY DEPTNO;

二、等值判断:DECODE

语法

sql

DECODE(判断字段, 值1, 返回值1, 值2, 返回值2, ..., 默认值)
  • 只支持单字段等值判断

示例:岗位汉化

sql

SELECT ENAME, JOB, DECODE(JOB, 'SALESMAN', '销售', 'MANAGER', '经理', 'CLERK', '文员', '职员') AS NEW_JOB FROM EMP;

三、集合运算

运算符含义
UNION ALL合并,不去重
UNION合并,去重(效率较低)
INTERSECT交集
MINUS差集(前一个结果集减去后一个)

示例

sql

SELECT ID FROM TABLEA UNION ALL SELECT ID FROM TABLEB; SELECT ID FROM TABLEA MINUS SELECT ID FROM TABLEB;

⚠️ 注意点

  • 上下两个SELECT字段个数、顺序、类型必须一致

  • 排序(ORDER BY)只能放在最后一个查询之后

  • 最终列名以第一个SELECT为准


四、EXISTS半连接

语法

sql

SELECT ... FROM 表A WHERE EXISTS (SELECT 1 FROM 表B WHERE 关联条件);
  • 只要子查询有返回行,EXISTS就为TRUE

  • 不关心子查询具体返回什么,通常写SELECT 1

示例:存在员工的部门

sql

SELECT D.DEPTNO FROM DEPT D WHERE EXISTS ( SELECT 1 FROM EMP E WHERE E.DEPTNO = D.DEPTNO );

示例:不存在员工的部门

sql

SELECT D.DEPTNO FROM DEPT D WHERE NOT EXISTS ( SELECT 1 FROM EMP E WHERE E.DEPTNO = D.DEPTNO );

EXISTSvsIN

对比项EXISTSIN
实现方式半连接嵌套遍历
子表大时效率更高效率低
固定值列表不支持支持(如IN (10,20)

五、行列转换

1. 行转列(多行 → 多列)

方法一:CASE WHEN

sql

SELECT SNAME, SUM(CASE WHEN CLASS = '语文' THEN SCORE END) AS 语文, SUM(CASE WHEN CLASS = '数学' THEN SCORE END) AS 数学, SUM(CASE WHEN CLASS = '英语' THEN SCORE END) AS 英语 FROM T_SCORE GROUP BY SNAME;
方法二:DECODE

sql

SELECT SNAME, MAX(DECODE(CLASS, '语文', SCORE)) AS 语文, MAX(DECODE(CLASS, '数学', SCORE)) AS 数学, MAX(DECODE(CLASS, '英语', SCORE)) AS 英语 FROM T_SCORE GROUP BY SNAME;
方法三:PIVOT(Oracle)

sql

SELECT * FROM T_SCORE PIVOT (SUM(SCORE) FOR CLASS IN ('语文' AS 语文, '数学' AS 数学, '英语' AS 英语));

2. 列转行(多列 → 多行)

  • 使用UNPIVOTUNION ALL


六、课堂练习示例

练习1:员工标签(前/后50%入职)

sql

SELECT DEPTNO, ENAME, SAL, CASE WHEN NT = 1 THEN '老员工' ELSE '新员工' END AS 员工标签 FROM ( SELECT DEPTNO, ENAME, SAL, HIREDATE, NTILE(2) OVER (PARTITION BY DEPTNO ORDER BY HIREDATE) AS NT FROM EMP );

练习2:按员工标签统计平均薪资

sql

SELECT CASE WHEN NT = 1 THEN '老员工' ELSE '新员工' END AS 员工标签, AVG(SAL) AS 平均薪资 FROM ( SELECT SAL, NTILE(2) OVER (PARTITION BY DEPTNO ORDER BY HIREDATE) AS NT FROM EMP ) GROUP BY CASE WHEN NT = 1 THEN '老员工' ELSE '新员工' END;

总结重点

  • CASE WHEN适用于复杂条件判断

  • DECODE适用于等值单字段判断

  • 集合运算注意字段一致性

  • EXISTS适合子表大的存在性判断

  • 行列转换常用CASE WHEN/DECODE/PIVOT

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询