0
0
0

第4章(下):SELECT查询全攻略——从单表到嵌套

2026-10-19
文章摘要
|

第 4 章(下):SELECT 查询全攻略——从单表到嵌套

查询是 SQL 的核心中的核心。本篇把 SELECT 从最简单的单表查询一路讲到嵌套查询,每个层次配标准例题。学完后,考试的综合 SQL 题基本都能覆盖。

一、SELECT 的完整语法骨架

SELECT [DISTINCT] 目标列
FROM   表 [JOIN 表2 ON 连接条件]
WHERE  行筛选条件
GROUP BY 分组列
HAVING 组筛选条件
ORDER BY 排序列 [ASC|DESC];

执行顺序(理解后能避免一半错误):FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY。

二、第一层:单表无条件查询

SELECT * FROM Student;                          -- 全部列
SELECT Sname, Sage FROM Student;                -- 指定列
SELECT Sname AS 姓名, 2026-Sage AS 出生年份 FROM Student;  -- 别名与计算列
SELECT DISTINCT Sdept FROM Student;             -- 去重

三、第二层:条件查询(WHERE)

常用条件运算:= <> > >= < <=、AND OR NOT、BETWEEN ... AND、IN (...)、LIKE、IS NULL。

SELECT Sname FROM Student
WHERE Sdept='计算机' AND Sage<=20;

SELECT Sno, Grade FROM SC
WHERE Cno='C01' AND Grade BETWEEN 80 AND 90;

SELECT Sno, Cno FROM SC WHERE Grade IS NULL;   -- 空值判断必须用 IS NULL

模糊匹配 LIKE:

  • %:任意长度字符;_:任意单个字符。
SELECT Sname FROM Student WHERE Sname LIKE '张%';   -- 张姓学生
SELECT Sname FROM Student WHERE Sname LIKE '__华';  -- 第三个字是华

四、第三层:排序与聚合

SELECT Sno, Grade FROM SC
WHERE Cno='C01'
ORDER BY Grade DESC;        -- 降序;ASC 升序(默认)

聚合函数(对一列计算统计值,忽略 NULL):

函数 含义
COUNT(*) / COUNT(列) 行数 / 该列非空个数
SUM(列) / AVG(列) 求和 / 平均
MAX(列) / MIN(列) 最大 / 最小

五、第四层:分组统计(GROUP BY + HAVING)

-- 每门课的选课人数与平均分
SELECT Cno, COUNT(Sno) AS 人数, AVG(Grade) AS 平均分
FROM SC
GROUP BY Cno;

-- 只看选课人数超过 30 的课程
SELECT Cno, COUNT(Sno) AS 人数
FROM SC
GROUP BY Cno
HAVING COUNT(Sno) > 30;

WHERE 与 HAVING 的区别(必考):WHERE 在分组前筛选行(不能用聚合函数);HAVING 在分组后筛选组(可用聚合函数)。

易错点:SELECT 后面出现的列,要么在 GROUP BY 里,要么在聚合函数里,否则报错。

六、第五层:多表连接查询

-- 两表:学生及其选课成绩
SELECT Student.Sno, Sname, Cno, Grade
FROM Student JOIN SC ON Student.Sno = SC.Sno;

-- 三表:学生姓名、课程名、成绩
SELECT Sname, Cname, Grade
FROM Student
JOIN SC ON Student.Sno = SC.Sno
JOIN Course ON SC.Cno = Course.Cno;

连接条件 = 主码 = 外码。忘记写 ON 连接条件会产生笛卡尔积(行数 = 两表之积),是新手第一大坑。

七、第六层:嵌套(子)查询

子查询 = 查询里再套查询,由内向外执行。

IN 形式(子查询结果是一列值):

-- 选修了'C01'课程的学生姓名
SELECT Sname FROM Student
WHERE Sno IN (SELECT Sno FROM SC WHERE Cno='C01');

比较形式(子查询结果单值):

-- 比全体学生平均年龄小的学生
SELECT Sname FROM Student
WHERE Sage < (SELECT AVG(Sage) FROM Student);

EXISTS 形式(存在量词,内层有结果则外层行保留):

-- 选修了C01的学生
SELECT Sname FROM Student S
WHERE EXISTS (SELECT * FROM SC WHERE SC.Sno=S.Sno AND Cno='C01');

八、综合练习(自测)

给定本文的 Student / Course / SC 三表,写出:

  1. 计算机系女生名单(按年龄升序);
  2. 各系的系名与人数(人数 ≥ 2 才显示);
  3. "数据库"这门课的最高分与平均分;
  4. 选课总门数超过 3 门的学生的姓名与门数;
  5. 没有选修'C02'课程的学生学号(提示:NOT IN)。

下一篇:第 5 章——数据更新、视图与索引。

支持与分享

如果这篇文章对你有帮助,欢迎分享给更多人或者给予支持!

评论

欢迎来到我的博客!