这篇SQL课堂笔记总结了多种数据查询和处理的核心技术。
主要内容包括:
1)条件判断的CASE WHEN和DECODE语法及应用场景;
2)集合运算(UNION、INTERSECT等)的使用要点;
3)EXISTS子查询的高效实现方式;
4)行列转换的多种实现方法(CASE WHEN、DECODE、PIVOT)。
笔记通过具体示例演示了薪资分段、部门统计、成绩表转换等典型场景,并对比了不同技术的适用情况,如EXISTS与IN的效率差异。
最后还提供了员工分类统计等练习题,帮助巩固知识点。
以下是根据你提供的课堂内容整理的结构化复习笔记,涵盖了CASE WHEN、DECODE、集合运算、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
| 对比项 | EXISTS | IN |
|---|---|---|
| 实现方式 | 半连接 | 嵌套遍历 |
| 子表大时 | 效率更高 | 效率低 |
| 固定值列表 | 不支持 | 支持(如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. 列转行(多列 → 多行)
使用
UNPIVOT或UNION 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