这次的练习是对上次SELECT语句的继续使用和延续操作。
字符匹配:[NOT] LIKE ‘<匹配串>’ [ESCAPE ‘<换码字符>’]
<匹配串>可以是一个完整的字符串,也可以含有通配符%和_
【例3.29】查询学号为201215121的学生的详细情况
当匹配串为固定字符串时,以下两种方式等价:
Select * from Student where Sno like '201215121'
Select * from Student where Sno ='201215121'
也就是说此时 ‘LIKE’等价于‘=’
匹配串为含有通配符的字符串时
增加一些测试数据之后的Student表
【例3.30】查询所有姓刘的学生的姓名、学号和性别
select Sname,Sno,Ssex from Student
where Sname like '刘%'
执行结果:
【例3.31】查询姓“刘”且全名为三个汉字的学生的姓名
select Sname from Student
where Sname like '刘__' /*这里是两个下划线*/
如果下划线是一个
select Sname from Student
where Sname like '刘_' /*这里是一个下划线*/
到这就有问题出现了,如果两个下划线是指两个字符,一个下划线指一个字符,那‘刘晨’这个元素就不会两次都出现。
百度原因:可以将Sname的数据类型由CHAR改为VARCHAR,或将代码改为
SELECT *
FROM Student
WHERE Sname LIKE '刘%' AND LEN(Sname)=3;
具体请见:数据库原理课本中模糊匹配 like 下划线匹配多字符问题
【例3.32】查询名字中第2个字为“阳”的学生的姓名和学号
SELECT Sname,Sno
FROM Student
WHERE Sname LIKE '_阳%'
增加一些测试用例后的运行效果为
【例3.33】查询所有不姓刘 的学生姓名、学号和性别
‘LIKE’与‘NOT LIKE’
SELECT Sname,Sno,Ssex
FROM Student
WHERE Sname not LIKE '刘%'
当需要查找的字符串中本就有通配符时,需要使用换码字符将通配符转义为普通字符
【例3.34】查询DB_Design课程的课程号和学分
SELECT Cno,Ccredit
FROM Course
WHERE Cname LIKE 'DB\_Design' escape '\'
【例3.35】查询以‘DB_’开头,且倒数第三个字符为i的课程的详细情况
SELECT *
FROM Course
WHERE Cname LIKE 'DB\_%i__' escape '\'
escape ’ \ ’ 表示 “\” 为换码字符
(PS:单引号与反斜线之间没有空格,我这里写是因为不加空格反斜线不显示😢)
escape ’ \ ’ 一定要有,不然会出现下面的情况
SELECT *
FROM Course
WHERE Cname LIKE 'DB\_%i__'
涉及空值的查询:IS NULL 或 IS NOT NULL
注意:“IS”不能用“=”代替
【例3.36】查询缺少成绩的学生的学号和相应的课程号
SELECT Sno,Cno
FROM SC
WHERE Grade is null
【例3.37】查询所有有成绩的学生学号和课程号
SELECT Sno,Cno
FROM SC
WHERE Grade is not null
多重查询:用逻辑运算符AND和OR来连接多个查询条件
AND的优先级高于OR
可以用括号改变优先级
【例3.38】查询计算机系年龄在20岁以下的学生姓名
SELECT Sname
FROM Student
WHERE Sdept='CS' and Sage<20
IN语句可以用OR语句改写
改写【例3.27】:查询计算机科学系(CS)、数学系(MA)和信息系(IS)学生的姓名和性别
SELECT Sname,Ssex
FROM Student
WHERE Sdept in ('CS','MA','IS')
/*等价于*/
SELECT Sname,Ssex
FROM Student
WHERE Sdept ='CS'or Sdept = 'MA'or Sdept ='IS'
运行结果完全一致!
ORDER BY子句
【例3.39】查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列
SELECT Sno,Grade
FROM SC
WHERE Cno='3'
order by Grade desc
【例3.40】查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列
SELECT *
FROM Student
order by Sdept,Sage desc
对于空值,排序时显示的次序由具体系统实现来决定
聚集函数
【例3.41】查询学生总人数
SELECT count(*)
FROM Student
【例3.42】查询选修了课程的学生人数
SELECT count(distinct Sno)
FROM SC
【例3.43】计算1号课程的学生平均成绩
SELECT avg(Grade)
FROM SC
where Cno='1'
【例3.44】查询选修1号课程的学生最高分数
SELECT max(Grade)
FROM SC
where Cno='1'
【例3.45】查询学生201215012选修课程的总学分数
SELECT sum(Ccredit)
FROM SC,Course
where Sno='201215122' and SC.Cno=Course.Cno
注意:这道题与后面的多表查询有联系。
这里包含学生选修课程,所以要用到SC表
又要计算学分总和,用到Course表
需要先将SC表和Course表做一下等值连接 SC.Cno=Course.Cno,然后做选择。
这块居然忘截图了,失误失误
GROUP BY子句
【例3.46】求各个课程号及相应的选课人数
SELECT Cno,count(Sno)
FROM SC
group by Cno
【例3.47】查询选修了3门以上课程的学生学号
SELECT Sno
FROM SC
group by Sno
having count(*)>3
【例3.48】查询平均成绩大于等于80分的学生学号和平均成绩
SELECT Sno,avg(Grade)
FROM SC
where avg(Grade)>=80
group by Sno
是不是感觉没毛病?No,No,No,这种写法是错误的,这是因为WHERE子句中是不能用聚集函数作为表达式的
正确的语句应为
SELECT Sno,avg(Grade)
FROM SC
group by Sno
having avg(Grade)>=80
好啦,到这里单表查询的内容以及练习就结束了🎉🎉🎉
点赞干嘛,愣着呀!