pgsql-视图与CTE
CTE 我们在写sql的时候,如果sql条件有那种嵌套的 SELECT * FROM ( SELECT * FROM ( SELECT ... -- 这里的代码已经缩进到太
pgsql-视图与CTE
发布时间:2026-04-16 (1天前)

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 里有效 永久保存在数据库里
类比 局部变量 全局公共函数
适用场景 仅仅为了让这一行长查询变好看 经常要用的复杂查询、报表统计
权限控制 非常强大(可以给用户看视图,但不给他看原表)