目录

知识

1.SELECT语句格式

2.选择表中若干列

例1:查询全体学生的学号与姓名。

例2:查询全体学生的学号、课程号和成绩。

3.查询全部列

例3.查询全体学生的记录

4.查询经过计算的列

例4.查询全体学生的姓名及其年龄。

例5.含字符串常量的列:查询全体学生的姓名和出生年份,并在出生年份列前

5.改变列标题(取别名)

例:

6.消除取值相同的记录

例6.在成绩表中查询有哪些学生修了课程,要求列出学生的学号。

7.查询满足条件的元组

8.比较大小

例7.查询所有系号是1号的班号和班名。

例8.查询考试成绩有不及格的学生的学号

9.确定范围

例9.查询所有系号在2和3之间的班号和班名。

例10.查询所有系号不在2和3之间的班号和班名。

例11.查询1995年3月出生的学生信息:

10.确定集合

例12 查询所有班名是“电子信息工程技术”、“电子声像”或“电子组装技术”

例13 查询班名既不是“电子信息工程技术”、也不是“电子声像”和“电子组

11.字符匹配

例14.查询学生表中姓‘张’的学生的详细信息。

例15.查询姓“张”且名字是3个字的学生姓名。

例16.查询学生表中姓‘张’、姓‘李’和姓‘刘’的学生的情况。

例17 查询学生表表中名字的第2个字为“小”或“大”的学生的姓名和学号。

例18 查询学生表中所有不姓“刘”的学生。

例19 从学生表表中查询学号的最后一位不是2、3、5的学生信息。

12.涉及空值的查询

例如,学生选修课程后还没有考试时,这些学生有选课记录,但没有考试成绩,

例21 查询还没有考试的学生的学号和相应的课程号。

例22 查询所有已经考试了的学生的学号和课程号。

13.多重条件查询

例23 查询所有系号大于1且班名以“电子 ” 开头的班号和班名。

例24 查询11212P和11214D班所有男生的学号、姓名、性别和班号。

14.对查询结果进行排序

例25 将学生按班号的升序排序。

例26 查询选修了“M01F011 ”号课程的学生的学号及其成绩,查询结果按成绩降

例27 查询全体学生的信息,查询结果按班号升序排列,同班的学生按出生年份

15.使用聚合函数汇总数据

例如,查询成绩最高的学生的学号,如下写法是错误的:

例28 统计学生总人数。

例29 统计选修了课程的学生的人数。

例30计算学号为“11214D24”的学生的考试总成绩之和。

例31 计算“M01F011”课程的学生的考试平均成绩。

例32 查询选修了“M01F011” 课程的最高分和最低分。

16.对查询结果进行分组计算

例33 统计每门课程的选课人数,列出课程号和人数。

例34 查询每名学生的选课门数和平均成绩。

17.使用HAVING

例38 查询学生表中人数大于等于3的班号和人数。

例39 查询平均成绩大于等于80的学生的学号、选课门数和平均成绩。

18.WHERE, GROUP BY, HAVING

例如,查询计算机系和信息管理系的学生人数:

19.多表查询 - 多表连接

20.内连接

例40 查询每个学生及其班级的详细信息。

例41 去掉例40中的重复列。

例42 查询重修学生的修课情况,要求列出学生的名字、所修课的课程号和成绩。

21.执行连接操作的过程

22.表别名

使用别名时例42可写为如下形式:

例43 查询所有学生的姓名、班名和系名。

例44 查询软件工程系所有学生的情况,要求列出学生姓名和所在的系。

例45 有分组的多表连接查询。查询每个班的学生的考试平均成绩。

例46 有分组和行过滤的多表连接查询。查询21226P班每门课程的选课人数、平

23.自连接

例47 查询与张三在同一个班学习的学生的姓名和所在的班号。

24.外连接

例49 查询学生的选课情况,包括选修了课程的学生和没有选修课程的学生。

例50 查询所有学生的学号、姓名、班号和班名,即使该学生无班号也列出学生。

例51. 查询21226P班没有选课的学生,列出学生姓名和性别。

例52. 统计21226P班每个学生的选课门数,包括没有选课的学生。

25.交叉连接

26.使用TOP限制结果集

例53 查询年龄最大的三个学生的姓名、性别及出生日期。

例54 查询操作系统考试成绩前三名的学生的姓名和成绩。

例55. 查询选课人数最少的两门课程(不包括没有人选的课程),列出课程号和

例56. 查询21226P班选课门数超过2门的学生中,考试平均成绩最高的前2名(包

27.UNION(并)

例60.查询系号是1和2的班级的班号、班名、系号,系号是1 的记录在前,2在后。

例61.查询要求同例60,但将查询结果按系号从大到小排序。

例62.查询系号不是1的班级的班号、班名、系号。

28.INTERSECT(交)

例63.查询有任课记录且担任班主任的教师号。

29.将查询结果保存到新表中

例64.查询班级表中的系号和班号,将查询结果保存到永久表系号班号表中,并

表单

TABLE SC[Sno Cno Grade]

TABLE Course[Cno Cname Credit Semester]

TABLE Student[Sno Sname Ssex Sage Sdept]

练习

题目

1. 查询计算机系的学生的姓名、年龄。

2. 查询成绩在 70~80 分之间的学生的学号、课程号和成绩。

3. 查询计算机系年龄在 18~20 之间且性别为“男”的学生的姓名、年龄。

4. 查询“C001”号课程的最高分。

5. 查询计算机系学生的最大年龄和最小年龄。

6. 统计每个系的学生人数。

7. 统计每门课程的选课人数和考试最高分。

8. 统计每个学生的选课门数和考试总成绩,并按选课门数升序显示结果。

9. 查询总成绩超过 200 分的学生,要求列出学号和总成绩。

10. 查询选课门数超过 2 门的学生的学号、平均成绩和选课门数。

11. 查询选了“C002”课程的学生的姓名和所在系。

12. 查询成绩 80 分以上的学生的姓名、课程号和成绩,并按成绩降序排列结果。

13. 查询计算机系男生修了“VB”的学生的姓名、性别和成绩。

14. 查询学生的选课情况,要求列出每位学生的选课情况(包括未选课的学生),并列出学

生的学号、姓名、课程号和考试成绩。

15. 查询哪些课程没有人选,要求列出课程号和课程名。

16. 查询计算机系没有选课的学生,列出学生姓名。

17. 列出“高等数学”课程考试成绩前三名的学生的学号、姓名、所在系和考试成绩。

18. 查询 VB 考试成绩最低的学生的姓名、所在系和 VB 成绩。

19. 查询姓王和李的学生的考试情况学号,姓名和成绩。

20. 查询“大学英语”课的选修情况,要求将查询结果放在一张新的永久表中,假设新表名为SC_1。

21. 查询“C001”课程的选课人数,要求将查询结果放在一张局部临时表中,假设新表名为SC_2。

22. 分别查询信息管理系和计算机系的学生的姓名、性别、修课名称、修课成绩,并要求将这两个查询结果合并成一个结果集。

23. 查询选了 VB 的学生学号、姓名、所在系和成绩,并对所在系进行如下处理:当所在系为“计算机系”时,显示“CS”;当所在系为“信息管理系”时,显示“IS”;当所在系为“通信工程系”时,显示“CO”;对其他系,均显示“OTHER”。

参考答案

1. 2. 3. 4. 5. 6. 7. 8. 9. 10.

11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23.


知识

1.SELECT语句格式

一个完整的SELECT语句包括6个子句,其中前面的2个子句是必不可少的,其他子句可以省略。

SELECT 语句的完整格式如下:

SELECT [DISTINCT] 目标列名序列-----要查看的列

FROM 表名或视图名------------------数据来源

[WHERE 条件表达式 ] ----------------查询条件

[GROUP BY 列名 --------------------分组依据

[ HAVING 组条件表达式]] ---------分组条件

[ORDER BY 列名 [ASC|DESC] 序列]----排序依据

2.选择表中若干列

查询表中用户感兴趣的部分属性列。

例1:查询全体学生的学号与姓名。

SELECT 学号,姓名 FROM 学生表

例2:查询全体学生的学号、课程号和成绩。

SELECT 学号,课程号,成绩 FROM 成绩表

3.查询全部列

例3.查询全体学生的记录

SELECT 学号, 姓名, 性别, 出生日期, 班号 FROM 学生表

等价于:

SELECT * FROM 学生表

*表示所有列

4.查询经过计算的列

例4.查询全体学生的姓名及其年龄。

SELECT 姓名, 2018-year(出生日期) FROM 学生表

例5.含字符串常量的列:查询全体学生的姓名和出生年份,并在出生年份列前

加一列,此列的每行数据均为“年龄”常量值。

SELECT 姓名, ‘年龄’, 2018-year(出生日期) FROM 学生表

5.改变列标题(取别名)

语法:

列名 | 表达式 [ AS ] 新列名

或:

新列名=列名 | 表达式

例:

SELECT 姓名, year(getdate())-year(出生日期) AS 年龄 FROM 学生表

6.消除取值相同的记录

例6.在成绩表中查询有哪些学生修了课程,要求列出学生的学号。

SELECT 学号 FROM 成绩表

结果中有重复的行。

用DISTINCT关键字可以去掉结果中的重复行。

DISTINCT关键字放在SELECT词的后边、目标列名序列的前边。

SELECT DISTINCT 学号 FROM 成绩表

7.查询满足条件的元组

8.比较大小

例7.查询所有系号是1号的班号和班名。

SELECT 班号, 班名 FROM 班级表 WHERE 系号= 1

例8.查询考试成绩有不及格的学生的学号

SELECT DISTINCT 学号 FROM 成绩表 WHERE 成绩< 60

9.确定范围

用BETWEEN…AND和NOT BETWEEN…AND

是逻辑运算符,可以用来查找属性值在或不在指定范围内的元组,其中

BETWEEN后边指定范围的下限,AND后边指定范围的上限。

BETWEEN…AND…的格式为:

列名 | 表达式 [ NOT ] BETWEEN 下限值 AND 上限值

如果列或表达式的值在(或不在)下限值和上限值范围内,则结果为True,表明

此记录符合查询条件。

BETWEEN…AND…包括边界值。

例9.查询所有系号在2和3之间的班号和班名。

SELECT 班号,班名 FROM 班级表 WHERE 系号 BETWEEN 2 AND 3

等价于:

SELECT 班号,班名 FROM 班级表 WHERE 系号 >=2 AND 系号<=3

例10.查询所有系号不在2和3之间的班号和班名。

SELECT 班号,班名 FROM 班级表 WHERE 系号 NOT BETWEEN 2 AND 3

等价于:

SELECT 班号,班名 FROM 班级表 WHERE 系号<2 OR 系号>3

对于日期类型的数据也可以使用基于范围的查找。

例11.查询1995年3月出生的学生信息:

SELECT 学号, 姓名, 性别, 出生日期 FROM 学生表

WHERE 出生日期 BETWEEN

'1995/3/1' AND '1995/3/31'

10.确定集合

用来查找属性值属于指定集合的元组。

格式为:

列名 [NOT] IN(常量1, 常量2,…常量n)

IN:当列中的值与IN中的某个常量值相等时,则结果为True,表明此记录为符合查

询条件的记录。

NOT IN:当列中的值与某个常量值相等时,结果为False,表明此记录为不符合查

询条件的记录。

例12 查询所有班名是“电子信息工程技术”、“电子声像”或“电子组装技术”

的班号和班名。

SELECT 班号, 班名 FROM 班级表

WHERE 班名 IN ('电子信息工程技术' , '电子声像‘, '电子组装技术')

等价于:

SELECT 班号,班名 FROM 班级表

WHERE 班名= ‘电子信息工程技术’ OR

班名 = ‘电子声像’ OR

班名 = ‘电子组装技术’

例13 查询班名既不是“电子信息工程技术”、也不是“电子声像”和“电子组

装技术”的班号和班名。

SELECT 班号,班名 FROM 班级表

WHERE 班名 NOT IN ('电子信息工程技术' , '电子声像‘, '电子组装技术')

等价于:

SELECT 班号,班名 FROM 班级表

WHERE 班名!= ‘电子信息工程技术’ AND

班名!= ‘电子声像’ AND

班名!= ‘电子组装技术’

11.字符匹配

一般形式为:

列名 [NOT ] LIKE <匹配串>

匹配串中可包含如下四种通配符:

_:匹配任意一个字符;

%:匹配0个或多个字符;

[ ]:匹配[ ]中的任意一个字符(若要比较的字符是连续的,则可以用连字符“-”表

达 );

[^ ]:不匹配[ ]中的任意一个字符。

例14.查询学生表中姓‘张’的学生的详细信息。

SELECT * FROM 学生表 WHERE 姓名 LIKE ‘张%’

例15.查询姓“张”且名字是3个字的学生姓名。

SELECT * FROM 学生表 WHERE 姓名 LIKE '张__’

如果把姓名列的类型改为nchar(20),在SQL Server 2012中执行没有结果。原因是

姓名列的类型是nchar(20),当姓名少于20个汉字时,系统在存储这些数据时自动

在后边补空格,空格作为一个字符,也参加LIKE的比较。可用rtrim()去掉右空格。

SELECT * FROM 学生表 WHERE rtrim(姓名) LIKE '张__'

例16.查询学生表中姓‘张’、姓‘李’和姓‘刘’的学生的情况。

SELECT * FROM 学生表 WHERE 姓名 LIKE '[张李刘]%’

例17 查询学生表表中名字的第2个字为“小”或“大”的学生的姓名和学号。

SELECT 姓名,学号 FROM 学生表 WHERE 姓名 LIKE '_[小大]%'

例18 查询学生表中所有不姓“刘”的学生。

SELECT 姓名 FROM 学生 WHERE 姓名 NOT LIKE '刘%’

例19 从学生表表中查询学号的最后一位不是2、3、5的学生信息。

SELECT * FROM 学生表 WHERE 学号 LIKE '%[^235]'

12.涉及空值的查询

空值(NULL)在数据库中表示不确定的值。

例如,学生选修课程后还没有考试时,这些学生有选课记录,但没有考试成绩,

因此考试成绩为空值。

判断某个值是否为NULL值,不能使用普通的比较运算符。

判断取值为空的语句格式为:

列名 IS NULL

判断取值不为空的语句格式为:

列名 IS NOT NULL

例21 查询还没有考试的学生的学号和相应的课程号。

SELECT 学号,课程号 FROM 成绩表

WHERE 成绩 IS NULL

例22 查询所有已经考试了的学生的学号和课程号。

SELECT 学号,课程号 FROM 成绩表

WHERE 成绩 IS NOT NULL

13.多重条件查询

在WHERE子句中可以使用逻辑运算符AND和OR来组成多条件查询。

使用AND谓词的语法格式如下:

布尔表达式1 AND 布尔表达式2 AND … AND 布尔表达式n

只有当全部的布尔表达式均为真时,整个表达式的结果才为真,只要有一个布尔

表达式的结果为假,则整个表达式结果即为假。

使用OR谓词的语法格式如下。

布尔表达式1 OR 布尔表达式2 OR … OR 布尔表达式n

表示只要其中一个布尔表达式为真,则整个表达式的结果即为真;只有当全部布

尔表达式的结果均为假时,整个表达式结果才为假。

例23 查询所有系号大于1且班名以“电子 ” 开头的班号和班名。

SELECT 班号,班名 FROM 班级表

WHERE 系号>1 AND 班名 LIKE '电子%’

例24 查询11212P和11214D班所有男生的学号、姓名、性别和班号。

SELECT 学号,姓名,性别,班号 FROM 学生表

WHERE (班号= ‘ 11212P ’ OR 班号= ‘ 11214D ’) AND 性别=‘男’

也可写为:

SELECT 学号,姓名,性别,班号 FROM 学生表

WHERE 班号 IN( ‘ 11212P ’ , ‘ 11214D ’)

AND 性别=‘男’

14.对查询结果进行排序

可对查询结果进行排序。

排序子句为:

ORDER BY <列名> [ASC | DESC ]

[,<列名> … ]

说明:按<列名>进行升序(ASC)或降序(DESC)排序,还可以按照别名或序

号进行排序。

例25 将学生按班号的升序排序。

SELECT * FROM 学生表

ORDER BY 班号

例26 查询选修了“M01F011 ”号课程的学生的学号及其成绩,查询结果按成绩降

序排列。

SELECT 学号,成绩 FROM 成绩表

WHERE 课程号='M01F011'

ORDER BY 成绩 DESC

例27 查询全体学生的信息,查询结果按班号升序排列,同班的学生按出生年份

降序排列。

SELECT * FROM 学生表

ORDER BY 班号, year(出生日期) DESC

SELECT 班号, year(出生日期) 出生年份

FROM 学生表

ORDER BY 班号,出生年份 DESC

15.使用聚合函数汇总数据

SQL提供的统计函数有:

COUNT(*):统计表中元组个数;

COUNT([DISTINCT] <列名>):统计本列列值个数;

SUM( <列名> ):计算列值总和;

AVG( <列名> ):计算列值平均值;

MAX( <列名> ):求列值最大值;

MIN( <列名> ): 求列值最小值。

上述函数中除COUNT(*)外,其他函数在计算过程中均忽略NULL值。

统计函数不能出现在WHERE子句中。

例如,查询成绩最高的学生的学号,如下写法是错误的:

SELECT 学号 FROM 成绩表

WHERE 成绩 = MAX(成绩)

例28 统计学生总人数。

SELECT COUNT(*) FROM 学生表

例29 统计选修了课程的学生的人数。

SELECT COUNT (DISTINCT 学号)

FROM 成绩表

例30计算学号为“11214D24”的学生的考试总成绩之和。

SELECT SUM(成绩) FROM 成绩表

WHERE 学号 = ‘11214D24 '

例31 计算“M01F011”课程的学生的考试平均成绩。

SELECT AVG(成绩) FROM 成绩表

WHERE 课程号 = ‘M01F011 ‘

例32 查询选修了“M01F011” 课程的最高分和最低分。

SELECT MAX(成绩) 最高分,

MIN(成绩) 最低分 FROM 成绩表

WHERE 课程号 = ‘M01F011 '

16.对查询结果进行分组计算

作用:可以控制计算的级别:对全表还是对一组。

目的:细化计算函数的作用对象。

分组语句的一般形式:

[GROUP BY <分组条件>]

[HAVING <组过滤条件>]

GROUP BY子句中的分组依据列必须是表中存在的列名,不能使用AS子句指派的

结果集列的别名。

带有GROUP BY 子句的SELECT语句的查询列表中只能出现分组依据列或统计函

数,因为分组后每个组只返回一行结果。

例33 统计每门课程的选课人数,列出课程号和人数。

SELECT

课程号, COUNT(课程号) AS 选课人数

FROM

成绩表

GROUP BY 课程号

该语句首先对查询结果按课程号的值分组,所有具有相同课程号值的元组归为一

组,然后再对每一组使用COUNT函数进行计算,求得每组的学生人数。

例34 查询每名学生的选课门数和平均成绩。

SELECT 学号,

COUNT(*) 选课门数,

AVG(成绩) 平均成绩

FROM 成绩表

GROUP BY 学号

17.使用HAVING

HAVING子句用于对分组后的结果再进行过滤,

它的功能有点像WHERE子句,但它用于组而不是单个记录。

在HAVING子句中可以使用统计函数,但在WHERE子句中则不能。

HAVING通常与GROUP BY子句一起使用。

例38 查询学生表中人数大于等于3的班号和人数。

SELECT 班号, COUNT(*) 人数

FROM 学生表

GROUP BY 班号

HAVING COUNT(*) >= 3

例39 查询平均成绩大于等于80的学生的学号、选课门数和平均成绩。

SELECT 学号, COUNT(*) 选课门数,

AVG(成绩) 平均成绩 FROM 成绩表

GROUP BY 学号

HAVING AVG(成绩) >= 80

18.WHERE, GROUP BY, HAVING

当查询语句的目标列中包含聚合函数时,若没有分组子句,则目标列中只能写聚

合函数,而不能再写其他列名。若包含分组子句,则在查询的目标列中除了可以

写聚合函数外,只能写分组依据列。

WHERE子句用来筛选FROM子句中指定的数据源所产生的行数据。

GROUP BY子句用来对经WHERE子句筛选后的结果数据进行分组。

HAVING子句用来对分组后的结果数据再进行筛选。

对于可以在分组操作之前应用的搜索条件,在WHERE子句中指定它们更有效,

这样可以减少参与分组的数据行。

应当在HAVING子句中指定的搜索条件应该是那些必须在执行分组操作之后应用

的搜索条件。

建议将所有行搜索条件放在WHERE子句中而不是HAVING子句中

例如,查询计算机系和信息管理系的学生人数:

SELECT Sdept, COUNT(*) FROM Student

GROUP BY Sdept

HAVING Sdept in ( '计算机系', '信息管理系’)

或:

SELECT Sdept, COUNT (*)

FROM Student

WHERE Sdept in ( '计算机系', '信息管理系')

GROUP BY Sdept

第二种写法比第一种写法效率要高,因为参与分组的数据会比较少。

19.多表查询 - 多表连接

若一个查询同时涉及两个或两个以上的表,则称之为连接查询。

连接查询是关系数据库中最主要的查询。

连接查询包括内连接、外连接和交叉连接等。

连接查询中用于连接两个表的条件称为连接条件或连接谓词。

一般格式为:

[<表名1.>]<列名1>=[<表名2.>]<列名2>

20.内连接

内连接语法如下:

SELECT …

FROM 表名

[INNER] JOIN 被连接表

ON 连接条件

例40 查询每个学生及其班级的详细信息。

SELECT * FROM 学生表

INNER JOIN 班级表 ON 学生表.班号=班级表.班号

结果中有重复的列:班号。

例41 去掉例40中的重复列。

SELECT 学号, 姓名,班级表.班号, 班名 FROM 学生表 JOIN 班级表

ON 学生表.班号=班级表.班号

例42 查询重修学生的修课情况,要求列出学生的名字、所修课的课程号和成绩。

SELECT 姓名, 课程号, 成绩

FROM 学生表 JOIN 成绩表

ON 学生表.学号 = 成绩表.学号

WHERE 状态 = '重修'

21.执行连接操作的过程

首先取表1中的第1个元组,然后从头开始扫描表2,逐一查找满足连接条件的元组,

找到后就将表1中的第1个元组与该元组拼接起来,形成结果表中的一个元组。

表2全部查找完毕后,再取表1中的第2个元组,然后再从头开始扫描表2, …

重复这个过程,直到表1中的全部元组都处理完毕为止。

22.表别名

可以为表提供别名,其格式如下:

<源表名> [ AS ] <表别名>

使用别名时例42可写为如下形式:

SELECT 姓名, 课程号, 成绩

FROM 学生表 S JOIN 成绩表 g

ON S.学号 = g.学号

WHERE 状态 = ‘重修’

注:如果为表指定了别名,则查询语句中其他所有用到表名的地方都要使用别名。

例43 查询所有学生的姓名、班名和系名。

SELECT 姓名,班名,系名

FROM 学生表 s JOIN 班级表 bjb

ON s.班号 = bjb.班号

JOIN 系表 xb ON bjb.系号 = xb.系号

例44 查询软件工程系所有学生的情况,要求列出学生姓名和所在的系。

SELECT 姓名, 系名

FROM 学生表 s JOIN 班级表 bjb

ON s.班号 = bjb.班号

JOIN 系表 xb ON bjb.系号 = xb.系号

WHERE 系名= '软件工程系

例45 有分组的多表连接查询。查询每个班的学生的考试平均成绩。

SELECT 班号,

AVG(成绩) AS 班平均

FROM 学生表 S JOIN 成绩表 g

ON S.学号 = g.学号

GROUP BY 班号

例46 有分组和行过滤的多表连接查询。查询21226P班每门课程的选课人数、平

均成绩、最高成绩和最低成绩。

SELECT 课程号, COUNT(*) AS Total,

AVG(成绩) AS Avg成绩,

MAX(成绩) AS Max成绩,

MIN(成绩) AS Min成绩

FROM 学生表 S JOIN 成绩表 g

ON S.学号 = g.学号

WHERE 班号 = '21226P'

GROUP BY 课程号

23.自连接

是一种特殊的内连接。

相互连接的表物理上为同一张表。

通过为两个表取别名,使之在逻辑上成为两个表

例47 查询与张三在同一个班学习的学生的姓名和所在的班号。

SELECT S2.姓名, S2.班号

FROM 学生表 S1 JOIN 学生表 S2

ON S1.班号= S2.班号

--是同一个班的学生

WHERE S1.姓名 = ‘张三’

-- S1表作为查询条件表

AND S2.姓名 != ‘张三’

-- S2表作为结果表

24.外连接

只限制一张表中的数据必须满足连接条件,而另一张表中数据可以不满足连接条

件。

外连接的语法格式为:

SELECT … FROM 表1 LEFT | RIGHT [OUTER]

JOIN 表2 ON <连接条件>

例49 查询学生的选课情况,包括选修了课程的学生和没有选修课程的学生。

SELECT 学生表.学号, 姓名, 课程号, 成绩

FROM 学生表 LEFT JOIN 成绩表

ON 学生表.学号 = 成绩表.学号

例50 查询所有学生的学号、姓名、班号和班名,即使该学生无班号也列出学生。

SELECT 学号, 姓名,学生表.班号, 班名

FROM 学生表 LEFT JOIN 班级表

ON 学生表.班号 = 班级表.班号

例51. 查询21226P班没有选课的学生,列出学生姓名和性别。

SELECT 姓名,性别

FROM 学生表 S LEFT JOIN 成绩表 g

ON S.学号 = g.学号

WHERE 班号 = '21226P'

AND g.学号 IS NULL

例52. 统计21226P班每个学生的选课门数,包括没有选课的学生。

SELECT S.学号 AS 学号,

COUNT(课程号) AS 选课门数

FROM 学生表 S LEFT JOIN 成绩表 g

ON S.学号 = g.学号

WHERE 班号 = '21226P’

GROUP BY S.学号

25.交叉连接

就是两张表的笛卡尔积

语法格式为:

SELECT … FROM

表1 CROSS JOIN 表2

可以直接写成:

SELECT … FROM

表1, 表2

26.使用TOP限制结果集

在进行查询时有时只希望列出结果集中的前几个结果,而不是全部结果。

例如,竞赛时可能只取成绩最高的前三名.

可以使用TOP谓词限制输出的结果。格式如下:

TOP n [PERCENT] [WITH TIES]

n为非负整数。

TOP n:表示取查询结果的前n行;

TOP n PERCENT:表示取查询结果前n%行;

WITH TIES:表示包括并列的结果。

例53 查询年龄最大的三个学生的姓名、性别及出生日期。

SELECT TOP 3 姓名, 性别,出生日期 FROM 学生表

ORDER BY 出生日期

若包括年龄并列第3名的学生,则:

SELECT TOP 3 WITH TIES 姓名, 性别,出生日期

FROM 学生表

ORDER BY 出生日期

例54 查询操作系统考试成绩前三名的学生的姓名和成绩。

SELECT TOP 3 WITH TIES 姓名, 成绩

FROM 学生表 S JOIN 成绩表 g

ON S.学号 = g.学号

JOIN 课程表 C ON C.课程号 = g.课程号

WHERE 课程名 = ‘操作系统'

ORDER BY 成绩 DESC

例55. 查询选课人数最少的两门课程(不包括没有人选的课程),列出课程号和

选课人数。

SELECT TOP 2 WITH TIES 课程号,

COUNT(*) 选课人数

FROM 成绩表

GROUP BY 课程号

ORDER BY COUNT(课程号) ASC

例56. 查询21226P班选课门数超过2门的学生中,考试平均成绩最高的前2名(包

括并列的情况)学生的学号,选课门数和平均成绩。

SELECT TOP 2 WITH TIES S.学号,

COUNT(*) 选课门数, AVG(成绩) 平均成绩

FROM 学生表 S JOIN 成绩表 g ON S.学号 = g.学号

WHERE 班号 = '21226P'

GROUP BY S.学号

HAVING COUNT(*) > 2

ORDER BY AVG(成绩) DESC

27.UNION(并)

使用 UNION可以实现将多个查询结果集合并为一个结果集。

SELECT 语句1

UNION [ ALL ]

SELECT 语句2

ALL表示在结果集中不去除重复的记录。如果没有指定ALL,则去除合并后结果集中的重复记录

所有查询语句中列的个数和列的顺序必须相同。

所有查询语句中对应列的数据类型必须兼容。

ORDER BY语句要放在最后一个查询语句的后边。

例60.查询系号是1和2的班级的班号、班名、系号,系号是1 的记录在前,2在后。

SELECT 班号, 班名, 系号

FROM 班级表 WHERE 系号= 1

UNION

SELECT 班号, 班名, 系号

FROM 班级表 WHERE 系号= 2

等价于:

SELECT 班号, 班名, 系号

FROM 班级表 WHERE 系号 IN (1,2) ORDER BY 系号

例61.查询要求同例60,但将查询结果按系号从大到小排序。

SELECT 班号, 班名, 系号

FROM 班级表 WHERE 系号= 1

UNION

SELECT 班号, 班名, 系号

FROM 班级表 WHERE 系号= 2

ORDER BY 系号 DESC

使用 EXCEPT可以实现在第一个结果集中去除第二个结果集中存在的记录。

SELECT 语句1

EXCEPT[ ALL ]

SELECT 语句2

所有查询语句中列的个数和列的顺序必须相同。

所有查询语句中对应列的数据类型必须兼容。

例62.查询系号不是1的班级的班号、班名、系号。

SELECT 班号, 班名, 系号 FROM 班级表

EXCEPT

SELECT 班号, 班名, 系号 FROM 班级表

WHERE 系号= 1

等价于:

SELECT 班号, 班名, 系号 FROM 班级表

WHERE 系号<>1

28.INTERSECT(交)

使用 INTERSECT可以查找两个结果集中同时存在的记录。

SELECT 语句1

INTERSECT[ ALL ]

SELECT 语句2

所有查询语句中列的个数和列的顺序必须相同。

所有查询语句中对应列的数据类型必须兼容。

例63.查询有任课记录且担任班主任的教师号。

SELECT 教师号 FROM 成绩表

INTERSECT

SELECT 班主任号 FROM 班级表

SELECT DISTINCT 教师号 FROM 成绩表 cjb

JOIN 班级表 bjb

ON cjb.教师号 =bjb.班主任号

29.将查询结果保存到新表中

如果希望将查询结果保存到一个表中,可通过在SELECT语句中使用INTO子句实现。

SELECT 查询列表序列 INTO <新表名>

FROM 数据源

-- 其他行选择、分组等语句

例64.查询班级表中的系号和班号,将查询结果保存到永久表系号班号表中,并

查询该表中记录。

SELECT 系号, 班号 INTO 系号班号表

FROM 班级表

用INTO子句创建的新表可以是永久表,也可以是临时表。临时表又根据其使用范

围分为两种:

局部临时表

通过在表名前加一个“#”来标识。

生存期为创建此局部临时表的连接的生存期,

只能在创建局部临时表的当前连接中使用;

全局临时表

通过在表名前加两个“#”来标识。

生存期为创建全局临时表的连接的生存期,

在生存期内可以被所有的连接使用。

表单

TABLE SC[Sno Cno Grade]

SELECT TOP (1000) [Sno],[Cno],[Grade]FROM [db].[dbo].[SC]

TABLE Course[Cno Cname Credit Semester]

SELECT TOP (1000) [Cno],[Cname],[Credit],[Semester]FROM [db].[dbo].[Course]

TABLE Student[Sno Sname Ssex Sage Sdept]

SELECT TOP (1000) [Sno],[Sname],[Ssex],[Sage],[Sdept]FROM [db].[dbo].[Student]

练习

题目

1. 查询计算机系的学生的姓名、年龄。

2. 查询成绩在 70~80 分之间的学生的学号、课程号和成绩。

3. 查询计算机系年龄在 18~20 之间且性别为“男”的学生的姓名、年龄。

4. 查询“C001”号课程的最高分。

5. 查询计算机系学生的最大年龄和最小年龄。

6. 统计每个系的学生人数。

7. 统计每门课程的选课人数和考试最高分。

8. 统计每个学生的选课门数和考试总成绩,并按选课门数升序显示结果。

9. 查询总成绩超过 200 分的学生,要求列出学号和总成绩。

10. 查询选课门数超过 2 门的学生的学号、平均成绩和选课门数。

11. 查询选了“C002”课程的学生的姓名和所在系。

12. 查询成绩 80 分以上的学生的姓名、课程号和成绩,并按成绩降序排列结果。

13. 查询计算机系男生修了“VB”的学生的姓名、性别和成绩。

14. 查询学生的选课情况,要求列出每位学生的选课情况(包括未选课的学生),并列出学生的学号、姓名、课程号和考试成绩。

15. 查询哪些课程没有人选,要求列出课程号和课程名。

16. 查询计算机系没有选课的学生,列出学生姓名。

17. 列出“高等数学”课程考试成绩前三名的学生的学号、姓名、所在系和考试成绩。

18. 查询 VB 考试成绩最低的学生的姓名、所在系和 VB 成绩。

19. 查询姓王和李的学生的考试情况学号,姓名和成绩。

20. 查询“大学英语”课的选修情况,要求将查询结果放在一张新的永久表中,假设新表名为SC_1。

21. 查询“C001”课程的选课人数,要求将查询结果放在一张局部临时表中,假设新表名为SC_2。

22. 分别查询信息管理系和计算机系的学生的姓名、性别、修课名称、修课成绩,并要求将这两个查询结果合并成一个结果集。

23. 查询选了 VB 的学生学号、姓名、所在系和成绩,并对所在系进行如下处理: 当所在系为“计算机系”时,显示“CS”; 当所在系为“信息管理系”时,显示“IS”; 当所在系为“通信工程系”时,显示“CO”; 对其他系,均显示“OTHER”。

参考答案

1.

SELECT [Sname],[Sage]FROM [db].[dbo].[Student]
WHERE [Sdept]= '计算机系'

2.

SELECT [Sno],[Cno],[Grade]FROM [db].[dbo].[SC]
WHERE [Grade] BETWEEN 70 AND 80

3.

SELECT [Sname],[Sage]FROM [db].[dbo].[Student]
WHERE [Sdept]='计算机系' AND [Sage] BETWEEN 18 AND 20 AND [Ssex]='男'

4.

SELECT [Cno],MAX([Grade])最高分FROM [db].[dbo].[SC]Group BY [Cno]
HAVING [Cno] = 'C001'

5.

SELECT [Sdept],MAX([Sage])最大年龄,MIN([Sage])最小年龄FROM [db].[dbo].[Student]GROUP BY [Sdept]
HAVING [Sdept] = '计算机系'

6.

SELECT [Sdept],COUNT(*)学生人数FROM [db].[dbo].[Student]
GROUP BY [Sdept]

7.

SELECT [Cno],COUNT(*)学生人数,MAX([Grade])最高分FROM [db].[dbo].[SC]
GROUP BY [Cno]

8.

SELECT [Sno],COUNT(*)选课门数,Sum([Grade])考试总成绩FROM [db].[dbo].[SC]
GROUP BY [Sno]
ORDER BY [选课门数]

9.

SELECT [Sno],Sum([Grade])考试总成绩FROM [db].[dbo].[SC]
GROUP BY [Sno]
HAVING Sum([Grade])>200

10.

SELECT [Sno],Avg([Grade])平均成绩,COUNT(*)选课门数FROM [db].[dbo].[SC]
GROUP BY [Sno]
HAVING COUNT(*)>2

11.

SELECT [Cno] 课程,[Sname] 学生姓名,[Sdept] 所在系FROM [db].[dbo].[SC] JOIN [db].[dbo].[Student] ON [db].[dbo].[SC].Sno=[db].[dbo].[Student].Sno
WHERE [Cno]='C002'

12.

SELECT [Sname] 学生姓名,[Cno] 课程号,[Grade] 成绩FROM [SC] JOIN [Student] ON [SC].Sno=[Student].Sno
WHERE [Grade]>80
ORDER BY [Grade] DESC 

13.

SELECT [Sname] 学生姓名,[Ssex] 性别,[Grade] 成绩FROM ([SC] JOIN [Student] ON [SC].Sno=[Student].Sno)JOIN [Course] ON [SC].Cno=[Course].Cno
WHERE [Sdept]='计算机系' AND [Ssex]='男' AND [Cname]='VB'

14.

SELECT [Student].[Sno] 学号,[Sname] 姓名,[Cno] 课程号,[Grade] 考试成绩FROM [SC] JOIN [Student] ON [SC].Sno=[Student].Sno

15.

SELECT [Course].[Cno] 课程号,[Cname] 课程名FROM [SC] JOIN [Course] ON [SC].Cno=[Course].Cno
WHERE [Grade] IS NULL

16.

SELECT [Sname] 学生姓名FROM [SC] JOIN [Student] ON [SC].Sno=[Student].Sno
WHERE [Grade] IS NULL

17.

SELECT TOP 3 [Student].[Sno] 学号,[Sname] 学生姓名,[Sdept] 所在系,[Grade] 成绩FROM ([SC] JOIN [Student] ON [SC].Sno=[Student].Sno)JOIN [Course] ON [SC].Cno=[Course].Cno
WHERE [Cname]='高等数学'
ORDER BY [Grade] DESC

18.

SELECT TOP 1 [Sname] 学生姓名,[Sdept] 所在系,[Grade] 成绩FROM ([SC] JOIN [Student] ON [SC].Sno=[Student].Sno)JOIN [Course] ON [SC].Cno=[Course].Cno
WHERE [Cname]='VB'
ORDER BY [Grade] 

19.

SELECT [Student].[Sno] 学号,[Sname] 姓名,[Grade] 成绩FROM [SC] JOIN [Student] ON [SC].Sno=[Student].Sno
WHERE [Sname] LIKE '[王李]%'

20.

SELECT [Student].[Sno],[Sname],[Grade],[Ssex],[Sage],[Sdept] INTO SC_1FROM ([SC] JOIN [Student] ON [SC].Sno=[Student].Sno)JOIN [Course] ON [SC].Cno=[Course].Cno
WHERE [Cname]='大学英语'
SELECT TOP (1000) [Sno],[Sname],[Grade],[Ssex],[Sage],[Sdept]FROM [SC_1]

21.

SELECT [Cno],COUNT(*)选课人数 INTO #SC_2FROM [db].[dbo].[SC]
GROUP BY [Cno]
HAVING [Cno]='C001'

22.

SELECT  [Sdept],[Sname] 学生姓名,[Ssex] 性别,[Cname] 修课名称,[Grade] 成绩FROM ([SC] JOIN [Student] ON [SC].Sno=[Student].Sno)JOIN [Course] ON [SC].Cno=[Course].Cno
WHERE [Sdept]='信息管理系'
UNION
SELECT  [Sdept],[Sname] 学生姓名,[Ssex] 性别,[Cname] 修课名称,[Grade] 成绩FROM ([SC] JOIN [Student] ON [SC].Sno=[Student].Sno)JOIN [Course] ON [SC].Cno=[Course].Cno
WHERE [Sdept]='计算机系'

23.

SELECT [Student].[Sno] 学号,[Sname] 学生姓名,Case [Sdept]
When '计算机系' then 'CS'
When '信息管理系' then 'IS'
When '通信工程系' then 'CO'
Else 'OTHER'
End as 所在系,[Grade] 成绩FROM ([SC] JOIN [Student] ON [SC].Sno=[Student].Sno)JOIN [Course] ON [SC].Cno=[Course].Cno
WHERE [Cname]='VB'

数据库系统实践 III 查询语句相关推荐

  1. 数据库系统实践 IV 查询插入修改删除操作

    知识 CASE函数 是一种多分支的函数,可以根据条件列表的值返回多个可能的结果表达式中的一个. 可用在任何允许使用表达式的地方,但不能单独作为一个语句执行. 分为: 简单CASE函数 搜索CASE函数 ...

  2. DataWhale第21期组队学习自然语言处理实践(知识图谱)task4— 用户输入->知识库的查询语句

    参考来源:https://github.com/datawhalechina/team-learning-nlp/blob/master/KnowledgeGraph_Basic/task04.md# ...

  3. 怎么做mysql查询系统_mysql数据库系统学习(一)---一条SQL查询语句是如何执行的?...

    一.第一节:一条sql查询语句是怎样执行的 5.5.5版本以后,默认使用存储引擎为InnoDB 不使用查询缓存,MySQL8.0没有查询缓存这个功能 总体来说:MySQL分为service层和存储引擎 ...

  4. MySQL的基本查询语句

    MySQL的基本查询语句 一.数据准备 CREATE TABLE `customers` (`cust_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '顾客I ...

  5. hive的条件查询语句_[一起学Hive]之九-Hive的查询语句SELECT

    关键字:Hive SELECT.ORDER BY.SORT BY.DISTRIBUTE BY.CLUSTER BY.Hive子查询.Hive虚拟列 八.Hive的查询语句SELECT 在所有的数据库系 ...

  6. mysql 子表 关联查询语句_mysql查询语句 和 多表关联查询 以及 子查询

    1.查询一张表: select * from 表名: 2.查询指定字段:select 字段1,字段2,字段3-.from 表名: 3.where条件查询:select 字段1,字段2,字段3 from ...

  7. mysql多表查询语句_mysql查询语句 和 多表关联查询 以及 子查询

    1.查询一张表:select * from 表名: 2.查询指定字段:select 字段1,字段2,字段3-.from 表名: 3.where条件查询:select字段1,字段2,字段3 frome ...

  8. mysql五大子句_MySQL的查询语句中可以使用以下哪个子句来表示分组查询

    [多选题]人类行为遗传学工作者倾向于把人的行为遗传分为哪几类 [填空题]MySQL的连接操作包括内连接.( )和交叉连接. [判断题]社会生活类尤其是人文风光类纪录片的解说则多用文学. 散文手法, 既 ...

  9. 【mysql技术内幕1】mysql基础架构-一条SQL查询语句是如何执行的

    文章目录 1 一条SQL查询语句是如何执行的 2 mysql体系结构 3 InnoDB存储引擎 4 总结 1 一条SQL查询语句是如何执行的 ​ 通常我们使用数据库,都是将数据库看成一个整体,我们的应 ...

  10. sql server查询历史进程_学习笔记 | SequoiaDB SQL查询语句执行过程

    本篇笔记将为大家介绍 SequoiaDB 巨杉数据库查询 SQL 语句的执行过程,以及查询语句执行过程中实例层.协调节点.编码节点.数据节点各自承担的功能. 应用程序或用户想要从数据库查询需要的数据, ...

最新文章

  1. docker php伪静态无效,docker 安装 thinkphp+nginx
  2. 用于显示本地通知的跨平台插件flutter_local_notifications
  3. Linux 之二 Linux 多线程
  4. CMake基础 第4节 动态库
  5. 100元左右的鼠标推荐
  6. 老板要做数字化转型,干了3个月的脏活累活,我被开除了
  7. [BZOJ1563][NOI2009]诗人小G[决策单调性优化]
  8. 初学opengl的一些知识整理-1
  9. python什么是调用_Python中包(package)的调用方式
  10. 深入理解Java Proxy机制
  11. 又被分治题卡住好几个小时!用最笨的方法搞懂分治法边界,告别死循环!
  12. 迅雷离线下载怎么使用?迅雷离线下载使用方法
  13. python-pygame小游戏之五子棋
  14. springboot 根据身份证号计算性别和年龄
  15. 【考研政治笔记】唯物论中物质观与意识观辨析
  16. python快速生成文字云_在Python中创建文字云或标签云
  17. 自动化成本高?那么如何获得最高的投资回报呢?
  18. Appium+Android+Python,关闭广告
  19. 乐理知识(和弦相关)
  20. 【飞桨】Seg:U-Net【2015 MICCAI】论文研读

热门文章

  1. Dart语言编程基础
  2. aspnetcore vue 下载zip文件,压缩包打不开的问题记录
  3. oracle改密码sql语句,Oracle 修改数据库密码
  4. 微软梁念坚谈新平台 企业跨界办公随需而变
  5. ValueError: Variable in_hidden/weights already exists, disallowed. Did you mean to set reuse=True or
  6. 7.ratings评价列表页的实现
  7. 脚本之家电子书下载:https://www.jb51.net/books/
  8. matlab上机作业,matlab上机作业(数字信号处理)
  9. java script 菜鸟教程_JavaScript 基础教程
  10. Result的类型分析和总结