CTE
我们在写sql的时候,如果sql条件有那种嵌套的
SELECT * FROM (
SELECT * FROM (
SELECT ... -- 这里的代码已经缩进到太平洋了
) AS inner_data
) AS outer_data;
这个sql看起来就很不直观了,我们可以里面的sql抽离成一个变量
比如枫枫网盘需要统计:“每个用户上传的文件总大小,并筛选出超过 1GB 的土豪用户”。
-- 使用 CTE 让代码逻辑清晰
WITH user_file_stats AS (
-- 第一步:先把每个人的总和算出来,起个名字叫 user_file_stats
SELECT
u.username,
SUM(f.file_size) as total_size,
COUNT(f.id) as file_count
FROM users u
LEFT JOIN cloud_files f ON u.id = f.user_id
GROUP BY u.username
)
-- 第二步:直接像查表一样查这个“变量”
SELECT * FROM user_file_stats
WHERE total_size > 1024 * 1024 * 1024; -- 筛选超过 1GB 的人
视图
视图是一张“虚拟表”。它不存储实际数据,只存储一条查询语句。当你查询视图时,它会跑一遍背后的 SQL。
如果你经常需要通过JOIN关联用户、文件、存储节点这三张表来查看“文件完整路径”,每次写 10 行 SQL 很累。
-- 1. 创建视图:一次封装,永久受益
CREATE VIEW v_file_detail_full AS
SELECT
f.id,
f.file_name,
u.username AS owner_name,
n.node_name AS storage_location,
f.created_at
FROM cloud_files f
JOIN users u ON f.user_id = u.id
JOIN storage_nodes n ON f.node_id = n.id;
-- 2. 以后查起来就像查单表一样爽
SELECT * FROM v_file_detail_full WHERE owner_name = 'fengfeng';
视图 vs CTE:怎么选?
| 特性 | CTE (WITH) | 视图 (View) |
|---|---|---|
| 生命周期 | 只在当前这条 SQL 里有效 | 永久保存在数据库里 |
| 类比 | 局部变量 | 全局公共函数 |
| 适用场景 | 仅仅为了让这一行长查询变好看 | 经常要用的复杂查询、报表统计 |
| 权限控制 | 无 | 非常强大(可以给用户看视图,但不给他看原表) |