You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效查询含特定学生的课程及该课程所有学生列表?

高效实现筛选含特定学生的课程并列出所有学生

原查询的问题出在WHERE子句的过滤时机:s.name = 'Alice'会在JOIN之后直接过滤掉所有非Alice的学生记录,导致最终聚合时只能拿到Alice的名字,丢失了同课程的其他学生。

更高效简洁的实现方式:用EXISTS筛选课程+一次关联聚合

可以通过EXISTS子句先锁定包含目标学生(Alice)的课程,再关联学生表获取该课程的所有学生进行聚合,只需要一次关联操作,比两次JOIN的效率更高:

SELECT 
  c.name, 
  GROUP_CONCAT(s.name SEPARATOR ',') AS student_list
FROM 
  Courses c
  JOIN Students s ON s.CourseID = c.ID
WHERE 
  EXISTS (
    SELECT 1 
    FROM Students s2 
    WHERE s2.CourseID = c.ID 
      AND s2.name = 'Alice'
  )
GROUP BY 
  c.ID, c.name

原理说明

  1. EXISTS是半连接查询:它只会检查课程是否存在Alice的记录,找到匹配项后立即停止,不需要返回所有匹配行,执行效率比子查询返回所有ID再用IN的方式更高。
  2. 主查询的JOIN Students会获取该课程下的所有学生记录,后续的GROUP_CONCAT就能完整聚合所有学生名字,不会丢失数据。

另一种等价写法:用IN子句筛选课程ID

如果习惯用IN子句,也可以先查询出Alice所在的课程ID,再关联聚合,效率和EXISTS接近:

SELECT 
  c.name, 
  GROUP_CONCAT(s.name SEPARATOR ',') AS student_list
FROM 
  Courses c
  JOIN Students s ON s.CourseID = c.ID
WHERE 
  c.ID IN (
    SELECT CourseID 
    FROM Students 
    WHERE name = 'Alice'
  )
GROUP BY 
  c.ID, c.name

为什么比两次JOIN高效

两次JOIN的写法通常是先关联筛选课程,再再次关联学生表,本质上是两次全表关联;而上面的方法只做一次学生表关联,筛选课程的操作是轻量的半连接/子查询,避免了重复关联带来的性能开销。

内容的提问来源于stack exchange,提问作者Cave Johnson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 07:57:05