
本文详解如何通过 inner join 准确查询报名“water aerobics”课程的会员信息,并按 member_id 降序排列,同时指出 where 子句中误用 like 通配符(%)导致查询为空的根本原因。
本文详解如何通过 inner join 准确查询报名“water aerobics”课程的会员信息,并按 member_id 降序排列,同时指出 where 子句中误用 like 通配符(%)导致查询为空的根本原因。
在处理多表关联查询时,过度依赖嵌套子查询(如 IN + 多层 SELECT)不仅可读性差、性能低,还容易因逻辑疏漏导致结果为空——正如本例中,原查询因错误地在精确匹配场景下使用 'Water Aerobics%'(含 % 的 LIKE 模式),导致 WHERE c.name = 'Water Aerobics%' 实际匹配零条记录(因为 = 不支持通配符),最终返回空集。
更规范、高效且语义清晰的写法是采用显式 INNER JOIN,逐层建立实体间的关系链:
Member → Enrollment → Class。该路径完全符合数据库的外键约束设计(Enrollment.member_ID 引用 Member.member_ID,Enrollment.class_ID 引用 Class.class_ID),能精准定位报名了特定课程的会员。
以下是推荐的正确 SQL 查询:
SELECT
m.member_ID,
m.name
FROM Member m
INNER JOIN Enrollment e ON m.member_ID = e.member_ID
INNER JOIN Class c ON e.class_ID = c.class_ID
WHERE c.name = 'Water Aerobics'
ORDER BY m.member_ID DESC;✅ 关键修正说明:
- 使用 INNER JOIN 替代嵌套 IN 子查询,提升可读性与执行效率;
- WHERE c.name = 'Water Aerobics' 采用精确等值匹配(=),而非带 % 的 LIKE —— 因为题目明确要求课程名称完全等于“Water Aerobics”,而非“以它开头”;
- 别名(m, e, c)简化书写并增强可维护性;
- ORDER BY m.member_ID DESC 确保结果严格按会员 ID 降序排列,符合题干要求。
⚠️ 注意事项:
- 若需模糊匹配(例如查找所有名称以 “Water Aerobics” 开头的课程),才应使用 LIKE:c.name LIKE 'Water Aerobics%';此时 = 与 % 混用将永远不匹配,务必区分语义;
- INNER JOIN 会自动过滤掉未报名任何课程的会员或未被报名的课程,这正符合本题“已 enrol 的会员”这一业务前提;
- 如需包含未报名课程的会员(即保留所有 Member 记录),应改用 LEFT JOIN 并调整过滤逻辑,但本题无需此操作。
掌握 JOIN 的思维模式,是写出健壮、可扩展 SQL 查询的基础。从关系路径出发建模,远比堆砌子查询更贴近数据库的本质设计逻辑。

















