最近在练习 SQL 题目时遇到一道关于EXISTS 子查询 + CASE WHEN + 别名命名的题目,错得挺彻底,但也学到了很多。特整理笔记记录,供大家参考。
一 题目:
客户是否有高额订单
目标: 查询客户ID、客户名,并判断是否下过任意单笔金额 ≥1000 的订单
说明:此处涉及3个表:Customers、Ordes、OrderItems。Orders中的cust_id是Customers的主键,Orders的order_num是OrderIems的主键(order_num,order_item)的一部分。
cust_id:顾客ID
cust_name:顾客名字
order_num:订单号
quantity:数量
item_price:价格
二 正确写法(MySQL):

三 关键点拆解与错因分析:
1 理解错误
误将判断条件“任意单笔金额 ≥1000”写成“顾客订单总金额≥1000”

2 EXISTS中的“SELECT 1”是什么?
这是一个EXISTS 子查询的惯用写法。
EXISTS用于判断“是否存在”某些行,只关心有没有结果,不关心具体返回什么。
SELECT后任意常数都可以,这里1只是占位,重点是查不查得到值。也可以写成SELECT *,但没必要。
只要子查询返回一行,EXISTS 就返回 TRUE。
错误理解:我一开始以为必须写成SELECT oi.order_num。
3 EXISTS 中的“WHERE o.cust_id = c.cust_id”是干嘛的?
这是关键的主查询与子查询的“关联条件”。
它确保子查询只查这个客户自己的订单。
若省略,会变成判断全体是否有人有大额订单,逻辑就错了。
错误理解:我忘记加WHERE o.cust_id = c.cust_id,结果返回的都是“是”。
4 “END AS 是否有大额订单”,这里的汉字为什么不加单引号?
是否有大额订单是列别名(字段名),在 MySQL 中不需要加单引号。
正确写法:END AS 是否有大额订单
错误写法:END AS '是否有大额订单'会被当成字符串,不是字段名。
5 为什么用 Customers 表当主表?
因为我们想找出“所有客户”,不管他有没有订单,所以以Customers为主表。
Orders只能查有下单记录的客户。
错误理解:我用了Orders表做主表,导致没有下单的客户完全漏掉。
四 总结:
1 查询顾客的单笔金额而不是总金额,用子查询更简单
2 SELECT 1:仅用于判断是否存在记录,不返回值
3 EXISTS 子句中加关联条件:必须加 WHERE o.cust_id = c.cust_id
4 AS 别名,这里的别名不加单引号(MySQL)
5 以 Orders 为主表应该用 Customers,确保所有客户都有结果
— END —
数据分析,一起努力。
Thryze|数据分析 × AI能力成长 × 效率工具探索