查询操作
1.使用SELECT子句选取字段
(1)选择所有列
【案例8-13】查询全体学生的学号、姓名、性别、出生日期、班级编号、电话、电子邮件和家庭地址。
select * from Student
或
select Student_No, Student_Name, Student_Sex,Student_Birthday,Student_ClassNo,Student_Telephone,Student_Email,Student_Addrexx,Student_Birthday
from Student
2)选择部分列
【案例8-14】查询全体学生的学号、姓名、性别。
select Student_No,Student_Name,Student_Sex
from Student
(3)为结果集中的列指定别名
为目标列取别名有下列3种方式:
select Student_Name 学号,Student_Name AS 姓名,性别=Student_Sex
from Student
(4)结果集为表达式
【案例8-16】查询SelectCourse表中的所有信息,并将结果集中的SelectCourse_Score(成绩)统一增加5分。
select SelectCourse_StudentNo,SelectCourse_CourseNo,
SelectCourse_Score=SelectCourse_Score+5
from SelectCourse
(5)消除重复行-DISTINCT关键字
【实例8-17】查询Student表中的班级编号,查询结果中消除重复行。
先执行下列语句查看效果:
select 班级编号=Student_ClassNo
from Student
使用DISTINCT关键字消除重复行:
select distinct 班级编号=Student_ClassNo
from Student
【实例】查询已选修课程的学生学号(消除重复行)。
select distinct 已选课学生学号=SelectCourse_StudentNo
from SelectCourse
(6)限制返回行数-TOP子句
【案例8-18】查询Student表中的所有列,在结果集中输出前3条记录。
select top 3 * from student
go
【案例8-19】查询Student表中的所有列,在结果集中输出前10%记录。
select top 10 percent * from Student
go
2.使用INTO子句创建新表
【案例8-20】将Student表中学号、姓名、性别的查询结果作为新建的临时表StudentTemp。并查看结果。
select Student_No,Student_Name,Student_Sex
into #StudentTemp
from Student
go
select * from #StudentTemp
go
【例】利用INTO子句创建Student2表,其结构同Student表结构(仅复制表结构):两种方式。
方式1:
select *
into Student2
from Student
where 1=2
方式2:
select top 0 *
into Student3
from Student
3.使用WHERE子句设置查询条件
(1)比较运算符
【案例8-21】查询SelectCourse表中成绩SelectCourse_Score大于80分的记录
select *
from SelectCourse
where SelectCourse_Score>80
【案例8-22】查询Student表中所有女生的学号、姓名。
select Student_No,Student_Name
from Student
where Student_Sex='女'
(2)范围运算符
【案例8-23】查询SelectCourse表中成绩在70~79分(包括70分和79分)之间的学生的学号和成绩。
select SelectCourse_StudentNo,SelectCourse_Score
from SelectCourse
where SelectCourse_Score between 70 and 79
等价的比较运算符:
select SelectCourse_StudentNo,SelectCourse_Score
from SelectCourse
where SelectCourse_Score>=70 and SelectCourse_Score<=79
【案例8-24】查询SelectCourse表中成绩不在70~79分之间的学生的学号和成绩。
select SelectCourse_StudentNo,SelectCourse_Score
from SelectCourse
where SelectCourse_Score not between 70 and 79
(3)集合运算符
【案例8-25】查询班级编号是“200701”和“200702”学生的姓名和性别。
select Student_Name,Student_Sex
from Student
where Student_ClassNo in('200701','200702')
等价的比较运算符:
select Student_Name,Student_Sex
from Student
where Student_ClassNo='200701'
or Student_ClassNo='200702'
【案例8-26】查询Student表中班级编号既不是“200701”,也不是“200702”的学生的姓名和性别。
select Student_Name,Student_Sex
from Student
where Student_ClassNo not in ('200701','200701')
等价的比较运算符:
select Student_Name,Student_Sex
from Student
where Student_ClassNo !='200701'
and Student_ClassNo!='200702'
(4)字符匹配
【案例8-27】查询Student表中所有姓“张”的学生的所有信息。
select *
from Student
where Student_Name like '张%'
【例】查询Student表中姓 “张”、姓“李”和姓“王”的学生的详细信息
select *
from Student
where Student_Name like '[张李王]%'
【例】查询Student表中学生名字的第2个字为“小”或“大”的学生的姓名和学号。
select Student_Name,Student_No
from Student
where Student_Name like '_[小大]%'
【例】查询Student表中所有不姓“张”的学生姓名
select Student_Name
from Student
where Student_Name not like '张%'
【例】查询Student表中学号的最后一位为5的学生信息。
select *
from Student
where Student_No like '%5'
【例】查询Student表中学号的最后一位为2或5的学生信息。
select *
from Student
where Student_No like '%[25]'
【例】查询Student表中学号的最后2位为25的学生信息。
select *
from Student
where Student_No like '%25'
【例】在Student表中查询学号的最后一位不是2、3、5的学生信息。
select *
from Student
where Student_No like '%[^235]'
【案例8-28】查询Student表中所有姓王且名字为3个汉字的学生的信息。
select *
from Student
where Student_Name like '王__'
(5)涉及空值的查询
【案例8-29】查询SelectCourse表中成绩为空的记录。
select *
from SelectCourse
where SelectCourse_Score is null
【案例】查询SelectCourse表中成绩非空的记录。
select *
from SelectCourse
where SelectCourse_Score is not null
(6)逻辑运算符-(多重条件查询)
【案例8-30】查询Student表中“200701”班所有男生的信息。
select *
from Student
where Student_No='200701'
and Student_Sex='男'
【案例】查询Student表中“200701”和“200701”班所有男生的信息。
先执行下列语句,查看结果正确否?原因何在?
select *
from Student
where Student_ClassNo='200701'
or Student_ClassNo='200702'
and Student_Sex='男'
注意:OR的优先级小于AND,要改变运算的顺序可以通过加括号的方式实现。
再执行下列代码,查看结果:
select *
from Student
where (Student_ClassNo='200701'
or Student_ClassNo='200702')
and Student_Sex='男'
等价集合运算代码:
select *
from Student
where Student_ClassNo in ('200701','200702')
and Student_Sex='男'
【案例】查询Student表中200701班所有姓“张”的所有学生的信息。
select *
from Student
where Student_ClassNo='200701'
and Student_Name like '张%'
【案例】查询Student表中姓“张”和姓“王”班所有学生的信息。
select *
from Student
where Student_Name like '张%'
or Student_Name like '王%'
【案例】查询Student表中姓“张”和姓“王”班所有男生的信息。
select *
from Student
where (Student_Name like '张%'
or Student_Name like '王%')
and Student_Sex='男'
select Sel
4.使用ORDER BY子句对结果集排序
【案例8-31】查询SelectCourse表中选修了课程代号为“20181”课程的学生的学号和成绩,查询结果按分数降序排列。
ectCourse_StudentNo,SelectCourse_Score
from SelectCourse
where SelectCourse_CourseNo='20181'
order by SelectCourse_Score desc
【案例8-32】查询Student表中全体学生情况,结果按所在班级编号的升序排列,同一班级中的学生按学号降序排列。
select *
from Student
order by Student_ClassNo,Student_No desc
案例】查询修了“C002”课程的学生的学号及成绩,查询结果按成绩降序排列。
select SelectCourse_StudentNo ,SelectCourse_Score
from SelectCourse
where SelectCourse_CourseNo='20182'
order by SelectCourse_Score
5.使用聚合函数统计数据
【案例8-33】查询Student表中学生总人数。
select count(*)
from Student
【案例8-34】查询SelectCourse表中已选修了课程的学生人数。
select count(distinct SelectCourse_StudentNo)
from SelectCourse
【案例8-35】计算SelectCourse表中“20181”号课程的学生平均成绩。
select avg(SelectCourse_Score)
from SelectCourse
where SelectCourse_CourseNo='20181'
【案例8-36】查询SelectCourse表中选修“20181”号课程的学生最高分数和最低分。
select max(selectcourse_score) 最高分,min(selectcourse_score) 最低分
from SelectCourse
where SelectCourse_CourseNo='20181'
使用GROUP BY子句 对数据进行分组统计
【案例8-37】统计SelectCourse表中各门课程的选课人数,输出课程代号和选课人数。
select 课程编号=SelectCourse_CourseNo,
选课人数=count(selectcourse_studentno)
from SelectCourse
group by SelectCourse_CourseNo
执行机制:对查询结果按SelectCourse_CourseNo的值分组,所有具有相同SelectCourse_CourseNo 值的元组为一组,然后再对每一组使用COUNT计算,求出每组的学生人数。
【案例8-38】统计Student表中各班学生的人数,输出班级编号和学生人数。
select 班级编号=Student_ClassNo, 学生人数=count(student_no)
from Student
group by Student_ClassNo
【案例】统计每个学生的选课门数和平均成绩。
select SelectCourse_StudentNo 学号,count(*) 选课门数,
avg(selectcourse_score) 平均成绩
from SelectCourse
group by SelectCourse_StudentNo
例】带WHERE子句的分组。统计每个班的女生人数。
select Student_ClassNo,count(*) 女生人数
from Student
where Student_sex='女'
group by Student_ClassNo
【例】按多个列分组。统计每个班的男生人数和女生人数以及男生的最大年龄和女生的最大年龄。结果按班级号的升序排序。
select Student_ClassNo,Student_Sex,count(*) 人数,Min(student_birthday) 最大年龄
from Student
group by Student_ClassNo,Student_Sex
order by Student_ClassNo
【案例8-39】查询SelectCourse表中选修了2门以上课程的学生学号。
select 学号=SelectCourse_StudentNo
from SelectCourse
group by SelectCourse_StudentNo having count(*)>2
处理过程为:先执行GROUP BY子句对SelectCourse表数据按SelectCourse_StudentNo进行分组,然后再用统计函数COUNT分别对每一组进行统计,最后筛选出统计结果满足大于2的组。
【例】查询选课门数大于等于4门的学生的平均成绩和选课门数。
select SelectCourse_StudentNo,avg(selectcourse_score) 平均成绩
from SelectCourse
group by SelectCourse_StudentNo
having count(*)>=4
【例】查询每个班级的男生人数。
select Student_ClassNo,count(Student_Sex) 男生
from Student
where Student_Sex='男'
group by Student_ClassNo
7.使用COMPUTE子句等价的with rollup
【案例8-40】查询Student表中的所有字段列,在结果集中显示各班的学生人数和该班的所有学生记录。
select Student_ClassNo,count(Student_NO) 人数
from Student
group by Student_ClassNo with Rollup
order by Student_ClassNo
8.连接查询
(1)内连接
【案例8-41】查询每个学生的基本信息及选课的情况。
select Student.*,SelectCourse.*
from Student join SelectCourse
on Student.Student_No=SelectCourse.SelectCourse_StudentNo
等价条件语句:
select Student.*,SelectCourse.*
from Student,SelectCourse
select Student.*,SelectCourse.*
from Student,SelectCourse
where student.Student_No=SelectCourse.SelectCourse_StudentNo
是否去掉了重复列?
不加Where条件如何?
如何组合两个有相同列的表?
【案例8-42】去掉重复列:查询每个学生的学号、姓名、选修的课程名、成绩。
select Student.Student_No,Student_Name,Course_Name,SelectCourse_Score
from Student,Course,SelectCourse
where student.Student_No=SelectCourse.SelectCourse_StudentNo
and Course.Course_No=SelectCourse.SelectCourse_CourseNo
【案例8-43】查询选修了编号为“20181”的课程且成绩大于70分的学生的学号、姓名、成绩。
select Student.student_No,Student_Name,SelectCourse_Score
from Student join SelectCourse
on (Student.Student_No=SelectCourse.SelectCourse_StudentNo
and SelectCourse_CourseNo='20181' and SelectCourse_Score>70)
等价条件语句:
select Student.Student_No,Student_Name,SelectCourse_Score
from Student,SelectCourse
where Student.Student_No=SelectCourse.SelectCourse_StudentNo
and SelectCourse_CourseNo='20181'
and SelectCourse_Score>70
【例】有分组的多表连接查询:
统计每个班的学生的考试平均成绩。
select Student_ClassNo as 班号,
avg(selectcourse_score) as 平均成绩
from Student S join SelectCourse
on s.Student_No=SelectCourse.SelectCourse_StudentNo
group by Student_ClassNo
【例】有分组和行选择条件的多表连接查询:
统计200701班学生每门课程的选课人数、平均成绩、最高成绩和最低成绩。
select SelectCourse_CourseNo,count(*) as 选课人数,
avg(selectcourse_score) as 平均成绩,
max(selectcourse_score) as 最高分,
min(selectcourse_score) as 最低分
from Student S join SelectCourse
on s.Student_No=SelectCourse.SelectCourse_StudentNo
where Student_ClassNo='200701'
group by SelectCourse_CourseNo
(2)外连接
【案例8-44】查询所有学生的选修情况,要求包括选修了课程的学生和没有修课的学生,显示他们的学号、姓名、课程编号、成绩。
select Student.Student_No,Student_Name,SelectCourse_CourseNo,SelectCourse_Score
from Student left join SelectCourse
on Student_No=SelectCourse.SelectCourse_StudentNo
(3)自连接
【例】查询与王大锤在同一个班学习的学生的姓名和所在的班级号。
select S2.Student_Name,S2.Student_ClassNo
from Student S1 join Student S2
on S1.Student_ClassNo=S2.Student_ClassNo
where S1.Student_Name='王大锤'
and S2.Student_Name!='王大锤'
【例】查询与“数据结构”在同一个学期开设的课程的课程名和开课学期
select C1.Course_Name,C1.Course_Term
from Course C1 join Course C2
on C1.Course_term=C2.Course_Term
where C2.Course_Name='数据结构'
【例】查询至少被两个学生选的课程的课程号。
select distinct a.SelectCourse_CourseNo
from SelectCourse a join SelectCourse b
on a.SelectCourse_CourseNo=b.SelectCourse_CourseNo
and a.SelectCourse_CourseNo!=b.SelectCourse_CourseNo
等价语句:
select SelectCourse_CourseNo
from SelectCourse
group by SelectCourse_CourseNo
having count(*)>1
9.嵌套查询
(1)带有比较运算符的子查询
【案例8-46】查询与学生“张杰”在同一个班级学习的所有学生的学号和姓名。
select Student_No,Student_Name
from Student
where Student_ClassNo=(select Student_ClassNo
from Student
where Student_Name='张杰'
)
(2)带有IN谓词的子查询
【案例8-46】查询与学生“张杰”在同一个班级学习的所有学生的学号和姓名。
select Student_No,Student_Name
from Student
where Student_ClassNo in (select Student_ClassNo
from Student
where Student_Name='张杰' )and Student_Name!='张杰'
【案例8-47】求选修了数据结构的学生学号和姓名。
select Student_No,Student_Name
from Student
where Student_No in (select SelectCourse_StudentNo
from SelectCourse
where SelectCourse_CourseNo in(Select Course_No
from Course
where Course_Name='数据结构'
)
)
(3)带有ANY、SOME或ALL谓词的子查询
【案例8-48】求其他班中比“200701”班某一学生出生日期小的学生。
select *
from Student
where Student_Birthday<any(select Student_Birthday
from Student
where Student_ClassNo='200701')
and Student_ClassNo<>'200701'
【案例8-49】求其他班中比“200702”班学生的出生日期都小的学生(即求出生日期小于“200702”班出生日期最小者的学生
select *
from Student
where Student_Birthday < all(select Student_Birthday
from Student
where Student_ClassNo='200702')
and Student_ClassNo<>'200702'
等价语句:
select *
from Student
where Student_Birthday<(select min(student_birthday)
from Student
where Student_ClassNo='200702')
and Student_ClassNo<>'200702'
(4)带有EXISTS谓词的子查询
相关子查询
【案例8-50】求选修了“20182”课程的学生姓名。
select Student_Name
from Student
where exists(select *
from SelectCourse
where Student.Student_No=SelectCourse_StudentNo
and SelectCourse_CourseNo='20182')
【案例8-51】求至少选修了学号为“201901”的学生所选修全部课程的学生学号和姓名。
select Student_No,Student_Name
from Student
where not exists (select *
from SelectCourse SC1
where SC1.SelectCourse_StudentNo='201901'and not exists(select *
from SelectCourse SC2
where Student.Student_No = SC2.SelectCourse_StudentNo
and SC2.SelectCourse_CourseNo=SC1.SelectCourse_CourseNo))
10.集合查询(查询结果的并、交、差运算)
(1)查询结果的并运算
【案例8-52】查询选修了“20191”课程或选修了“20182”课程的学生学号。
select SelectCourse_StudentNo from SelectCourse where SelectCourse_CourseNo='20191'
union --all
select SelectCourse_StudentNo from SelectCourse where SelectCourse_CourseNo='20182'
等价语句:
select distinct(SelectCourse_StudentNo)
from SelectCourse
where SelectCourse_CourseNo='20191' or SelectCourse_CourseNo='20182'
(2)查询结果的交运算
【例】查询王小蒙和张梦幻所选的相同课程,列出课程名和学分。(即同时被王小蒙和张梦幻选的课程)
select Course_Name,Course_Credits
from Student S JOIN SelectCourse on S.Student_No=SelectCourse_StudentNo
join Course C on C.Course_No= SelectCourse_CourseNo
where Student_Name='王小蒙'
intersect
select Course_Name,Course_Credits
from Student S JOIN SelectCourse on S.Student_No=SelectCourse_StudentNo
join Course C on C.Course_No= SelectCourse_CourseNo
where Student_Name='张梦幻'
用IN形式的等价语句:
select Course_Name,Course_Credits
from Course
where Course_No in(--王小蒙的课程
select Course_No
from SelectCourse join Student S
on S.Student_No=SelectCourse_StudentNo
join Course C on C.Course_No= SelectCourse_CourseNo
where Student_Name='王小蒙')
and Course_No in(--张梦幻的课程
select Course_No
from SelectCourse join Student S
on S.Student_No=SelectCourse_StudentNo
join Course C on C.Course_No= SelectCourse_CourseNo
where Student_Name='张梦幻')
(3)查询结果的差运算
【案例8-53】求选修了“20182”课程但没有选修“20181”课程的学生学号。
select SelectCourse_StudentNo
from SelectCourse
where SelectCourse_CourseNo='20182'
except
select SelectCourse_StudentNo
from SelectCourse
where SelectCourse_CourseNo='20181'
教材上的另一种解法:
select SelectCourse_StudentNo
from SelectCourse SC1
where SelectCourse_CourseNo='20182' and not exists
(select SelectCourse_StudentNo
from SelectCourse SC2
where SC1.SelectCourse_StudentNo=SC2.SelectCourse_StudentNo
and SC2.SelectCourse_StudentNo='20181')
【例】查询张梦幻选了但王小蒙没有选的课程的课程名和开课学期。
select Course_Name,Course_Term
from Course C join SelectCourse on C.Course_No=SelectCourse_CourseNo
join Student S on S.Student_No=SelectCourse_StudentNo
where Student_Name='张梦幻'
except
select Course_Name,Course_Term
from Course C join SelectCourse on C.Course_No=SelectCourse_CourseNo
join Student S on S.Student_No=SelectCourse_StudentNo
where Student_Name='王小蒙'
11.实训——学籍管理系统的查询操作
【实训8-1】求“200701”班选修课程大于等于2门课的学生的学号和平均成绩,并按平均成绩从高到低排序。
select Student.Student_No,平均成绩=avg(SelectCourse_score)
from Student,SelectCourse
where student.Student_No=SelectCourse.SelectCourse_StudentNo
and Student.Student_ClassNo='201901'
group by Student_No having count(*)>=2
order by avg(SelectCourse_Score)desc
【实训8-2】求“20182”课程的成绩高于“王小蒙”同学的学生学号和成绩。
select SelectCourse_StudentNo,SelectCourse_Score
from SelectCourse
where SelectCourse_CourseNo='20182'
and SelectCourse_Score>(select SelectCourse_Score
from SelectCourse
where SelectCourse_CourseNo='20182'
and SelectCourse_StudentNo=(select Student_No
from Student
where Student_Name='王小蒙'))
【实训8-3】查询“物理”课程成绩低于85分的学生的姓名和年龄。
select Student_Name,年龄=year(getdate())-year(student_Birthday)
from Student
where Student_No in(select SelectCourse_StudentNo
from SelectCourse
where SelectCourse_Score<85
and SelectCourse_CourseNo in(select Course_No
from Course
where Course_Name='物理'))