本文总结了SQL中临时表(CTE)、视图和正则表达式的核心知识点。
临时表部分重点讲解WITH子句的编写规范、使用优势(逻辑拆分、提高可读性)和连续登录天数计算案例,强调引用顺序和必须包含最终SELECT的注意事项。
视图部分对比普通视图与物化视图的存储特性,说明视图在封装逻辑和安全性方面的作用。
正则表达式部分详解Oracle四大核心函数(REGEXP_LIKE/SUBSTR/REPLACE/INSTR)的用法,包含字符串匹配、截取、替换和位置查找的典型示例,特别强调正则模式符号的应用技巧。
复习建议聚焦连续登录问题分析、视图封装价值和正则匹配/截取功能的重点练习。
以下是根据你的课堂笔记整理的结构化复习文档,适合学生快速理解和复习重点知识点。
📘 课堂笔记:临时表、视图与正则表达式
一、临时表(WITH 子句 / CTE)
✅ 基本写法
sql
WITH 临时表名1 AS (
SELECT 查询
),
临时表名2 AS (
SELECT 查询
)
SELECT 任意字段
FROM 任意临时表;
✅ 好处
-
将复杂逻辑拆分成多个简单步骤
-
提高代码可读性和可维护性
✅ 示例:最大连续登录天数 & 最近连续登录天数
sql
WITH T1 AS (
SELECT USER_ID, LOGIN_DATE,
ROW_NUMBER() OVER (PARTITION BY USER_ID ORDER BY LOGIN_DATE) AS RN
FROM T_LOGIN
),
T2 AS (
SELECT USER_ID, LOGIN_DATE, RN,
LOGIN_DATE - RN AS RR
FROM T1
),
T3 AS (
SELECT USER_ID, RR, COUNT(1) AS CNT
FROM T2
GROUP BY USER_ID, RR
)
SELECT DISTINCT
USER_ID,
MAX(CNT) OVER (PARTITION BY USER_ID) AS 最大连续,
FIRST_VALUE(CNT) OVER (PARTITION BY USER_ID ORDER BY RR DESC) AS 最近连续
FROM T3;
⚠️ 注意点
-
只能从上往下引用临时表
-
临时表仅在当前 SQL 中生效
-
必须 写最终的
SELECT语句
❌ 错误示例1:顺序引用错误
sql
WITH T1 AS (...),
T3 AS (SELECT * FROM T2), -- T2 还未定义
T2 AS (...)
SELECT * FROM T3;
❌ 错误示例2:没有最终 SELECT
sql
WITH T1 AS (...),
T2 AS (...)
-- 缺少 SELECT
二、视图(VIEW)
✅ 作用
-
封装一段
SELECT语句 -
避免重复复杂查询
-
隐藏底层表结构,增强安全性
✅ 创建语法
sql
CREATE OR REPLACE VIEW 视图名 AS
SELECT 语句;
✅ 示例
sql
CREATE OR REPLACE VIEW EMP_V AS
SELECT ENAME, SAL, E.DEPTNO, DNAME, LOC
FROM EMP E
INNER JOIN DEPT D ON E.DEPTNO = D.DEPTNO;
✅ 使用方式(和表一样)
sql
SELECT * FROM EMP_V;
SELECT LOC, COUNT(1) FROM EMP_V GROUP BY LOC;
🧠 区别对比
| 类型 | 是否存储数据 | 占用空间 | 使用场景 |
|---|---|---|---|
| 普通视图 | ❌ 不存储 | 无 | 封装逻辑,避免重复 |
| 物化视图 | ✅ 存储数据 | 有 | 提升性能,类似表 |
| 表 | ✅ 存储数据 | 有 | 持久化存储 |
三、正则表达式(Oracle)
✅ 四个核心函数
| 函数 | 说明 |
|---|---|
REGEXP_LIKE |
正则模糊匹配 |
REGEXP_SUBSTR |
正则截取子串 |
REGEXP_REPLACE |
正则替换 |
REGEXP_INSTR |
正则查找位置(整数索引) |
✅ 常用正则匹配项
| 表达式 | 含义 |
|---|---|
^ |
字符串开始 |
$ |
字符串结束 |
[A-Z] |
任意大写字母 |
[0-9] |
任意数字 |
[^0-9] |
非数字 |
{M} |
重复 M 次 |
+ |
至少 1 次 |
[^] |
非(取反) |
1️⃣ REGEXP_LIKE(匹配)
sql
-- 姓名必须是 5 位大写字母
SELECT * FROM EMP
WHERE REGEXP_LIKE(ENAME, '^[A-Z]{5}$');
-- 手机号校验
SELECT 1 FROM DUAL
WHERE REGEXP_LIKE('13112345678', '^1[3456789][0-9]{9}$');
2️⃣ REGEXP_SUBSTR(截取)
sql
-- 按 - 分割,取第 4 段
SELECT REGEXP_SUBSTR('中国-浙江省-杭州市-西湖区', '[^-]+', 1, 4) FROM DUAL;
-- 提取第 4 组连续字母
SELECT REGEXP_SUBSTR('DS333DAS5D5AS5DA6', '[A-Z]+', 1, 4) FROM DUAL;
3️⃣ REGEXP_REPLACE(替换)
sql
-- 统计数字 1 的个数
SELECT LENGTH(REGEXP_REPLACE('10101001010', '[^1]', '')) FROM DUAL;
-- 姓名脱敏:首字母 + *** + 尾字母
SELECT
ENAME,
SUBSTR(ENAME,1,1) ||
REGEXP_REPLACE(SUBSTR(ENAME,3), '[A-Z]', '*') ||
SUBSTR(ENAME,-1) AS NEW_ENAME
FROM EMP;
4️⃣ REGEXP_INSTR(位置)
sql
-- 查找第 3 组数字的起始位置
SELECT REGEXP_INSTR('JBJ34J33J45J', '[0-9]+', 1, 3) FROM DUAL;
-- 查找第 2 组非字母的起始位置
SELECT REGEXP_INSTR('8932BJ3B2BJ', '[^A-Z]+', 1, 2) FROM DUAL;
✅ 复习建议
-
临时表:重点掌握 连续登录问题 的拆分思路
-
视图:理解 封装逻辑 和 安全控制
-
正则:重点练习
REGEXP_LIKE和REGEXP_SUBSTR