找出所有累计消费金额超过 10000 元的"高价值用户"。
使用CTE查询高价值用户(消费>10000)
sql 语句如下
WITH high_value_users AS (
SELECT u.id, u.name, SUM(o.amount) AS total_spent
FROM users u
JOIN orders o ON u.id = o.user_id
GROUP BY u.id
HAVING total_spent > 10000
)
SELECT * FROM high_value_users;
如何理解这句sql呢?
这个 SQL 的作用是:
我将它拆成 3 层,一步步讲清楚。
第一步:先看最核心的查询(去掉 CTE)
SELECT u.id, u.name, SUM(o.amount) AS total_spent
FROM users u
JOIN orders o ON u.id = o.user_id
GROUP BY u.id
HAVING SUM(o.amount) > 10000;
这段的意思是:
-
把
users表和orders表通过user_id关联起来 -
按
u.id(每个用户)分组 -
对每个用户的订单金额求和:
SUM(o.amount) -
用
HAVING筛选出总和大于 10000 的用户
结果会得到一张表,列是:id, name, total_spent(比如张三消费了 15000 元)。
第二步:CTE 做了什么?
WITH high_value_users AS (
-- 上面那段查询放在这里
)
WITH ... AS ... 的作用是:给这段查询起一个临时名字 ,叫 high_value_users。 就像你在纸上先算出中间结果,给它取个名字,后面可以直接引用。
第三步:主查询使用这个临时表
SELECT * FROM high_value_users;
就是从刚才那个临时表里取出所有列(id, name, total_spent)。
合起来完整逻辑
-
先计算每个用户的总消费金额,只保留 > 10000 的用户 → 结果放入
high_value_users -
然后从
high_value_users中显示所有数据
实际执行效果:输出所有高价值用户的 ID、姓名、总消费金额。
为什么用 CTE(而不是直接写查询)?
在这个简单例子中,直接用子查询或 HAVING 就够,但 CTE 的好处是:
-
当后面需要多次使用这个"高价值用户"结果时(比如还要去关联其他表),不用重复写相同的聚合逻辑
-
让 SQL 更易读:先定义"高价值用户是什么",再查询它
类比帮助你理解
你让助手先去仓库里把"价格超过 1 万元的商品"全部挑出来,放在一个临时货架上,并给这个货架贴上标签 "贵重商品"。 然后你命令:"把贵重商品清单打印出来"。
WITH 贵重商品 AS (挑货逻辑)→ 定义临时货架
SELECT * FROM 贵重商品→ 打印清单