SQL面试题更新 2026-08-05

请写出一个 SQL 查询,找出那些名下至少存在一个订单其金额大于 200 的客户,并返回这些客户的姓名。

编码实现方案权衡SQL

考察说明

考查对 SQL 分组、聚合或子查询与条件过滤的综合应用能力,以及能否用正确且高效的写法解决‘至少一次’类业务查询。

回答思路

  1. 【回答框架 1】该查询的语义是筛选出至少有一个订单金额超过 200 的客户,而不是所有订单金额均超过 200。常见实现方式是使用 EXISTS 子查询,连接订单表并过滤金额大于 200,再关联客户表返回姓名,这样能在找到首个满足条件的订单后提前终止,通常效率较高。
  2. 【回答框架 2】另一种写法是使用 IN 子查询,先从订单表中选出金额大于 200 的不重复客户编号,再在客户表中用 WHERE IN 过滤。该写法逻辑清晰,但若订单表较大且金额条件选择性不高,可能存在性能开销。
  3. 【回答框架 3】还可以采用 JOIN 加 GROUP BY 与 HAVING 的方式,对订单表按客户编号分组,并设置 HAVING MAX(订单金额) > 200 或 COUNT(SUM(条件)) 等条件,然后与客户表关联。这种方式需要先分组,可能带来较大中间结果,在数据量小或 SQL 优化器可下推时也可行。
  4. 【回答框架 4】实际生产中,建议结合索引情况选择:订单表(客户编号、金额)上的复合索引能显著加速 EXISTS 或内连接。若客户表很小而订单表很大,EXISTS 通常较优;若两者规模相近,IN 与 EXISTS 优化后可能等价。
  5. 【关键点 1】使用 EXISTS 或 IN 子查询可准确表达‘至少一个’语义。
  6. 【关键点 2】使用 JOIN 时需要用 DISTINCT 去重,防止同一客户因多个满足条件的订单而被重复返回。
  7. 【关键点 3】若选用 GROUP BY 方案,需用 HAVING 配合条件表达式,例如 SUM(CASE WHEN 金额 > 200 THEN 1 ELSE 0 END) > 0。
  8. 【易错点 1】避免直接用 JOIN 后不加 DISTINCT,因为一个客户可能有多个超 200 的订单,导致客户姓名重复出现。
  9. 【易错点 2】注意金额字段的数据类型,若为浮点数,比较时需考虑精度,但一般业务上直接比较即可。
  10. 【易错点 3】不要误写为 ‘所有订单金额都大于 200’ 的条件,例如使用 MIN(金额) > 200,那将改变查询语义。