字符匹配
谓词:[NOT] LIKE ‘<匹配串>’ [ESCAPE ‘<换码字符>’]
- 当匹配串中的信息为详细信息是,LIKE 的作用相当于’='
【例 3.29】查询学号为201215121的学生的详细情况。
SELECT *
FROM Student
WHERE Sno LIKE '201215121';
等价于
SELECT *
FROM Student
WHERE Sno = '201215121';
2. 模糊查询
<匹配串>可以是一个完整的字符串,也可以含有通配符%和_
(1)%(百分号)代表任意长度(长度可以为0)的字符串
emmmm,举个栗子叭
比如a%b表示任意以a开头,以b结尾的任意长度的字符串
可以为ab,也可以为accccccb
(2)_(下横线)代表任意单个字符
比如a_b表示以a开头,以b结尾的长度为3的任意字符串
【例 3.30】查询所有姓刘学生的姓名、学号和性别。
SELECT Sname,Sno,Ssex
FROM Student
WHERE Sname LIKE '刘%';
这里在做试验的过程中,为了检验正确与否,可以将Student表中的所有信息都输出出来
【例 3.31】查询姓"欧阳"且全名为三个汉字的学生的姓名。
SELECT Sname
FROM Student
WHERE Sname LIKE '欧阳_';
如果查询姓’欧阳’全名为任意字符的学生姓名,则使用
SELECT Sname
FROM Student
WHERE Sname LIKE '欧阳%'
这里有一个小细节需要注意:
数据库字符集为ASCII时,一个汉字需要两个_
数据库字符集为GBK时,一个汉字需要一个_
【例 3.32】查询名字中第2个字为"阳"字的学生的姓名和学号。
SELECT Sname,Sno
FROM Student
WHERE Sname LIKE '_阳%';
【例 3.33】查询所有不姓刘的学生姓名、学号和性别。
SELECT Sname,Sno,Ssex
FROM Student
WHERE Sname NOT LIKE '刘%';
这里NOT LIKE 中的NOT 和 NOT BETWEEN … AND …中的NOT 有异曲同工之妙
3 使用换码字符将通配符转义为普通字符
【例 3.34】查询DB_Design课程的课程号和学分。
这里的课程名有些特殊,因为在SQL语句中,代表的是一个字符,那么真实的_又该如何表示呢???这就需要使用换码字符将通配符转义为普通字符,**ESCAPE '’ 表示“ _” 为换码字符**
SELECT Cno,Ccredit
FROM Course
WHERE Cname LIKE 'DB\_Design'ESCAPE'\';
【例 3.35】查询以"DB_"开头,且倒数第3个字符为 i的课程的详细情况。
SELECT *
FROM Course
WHERE Cname LIKE 'DB\_%i__'ESCAPE'\';
4 涉及空置的查询
谓词:IS NULL 或 IS NOT NULL
"IS"不能用"="代替
【例 3.36】某些学生选修课程后没有参加考试,所以有选课记录,但没 有考试成绩。查询缺少成绩的学生的学号和相应的课程号。
SELECT Sno,Cno
FROM SC
WHERE Grage IS NULL
【例 3.37】查所有有成绩的学生学号和课程号。
SELECT Sno,Cno
FROM SC
WHERE Grade IS NOT NULL;
- 多重条件查询
逻辑运算符:AND 和 OR 来连接多个查询条件
AND 的优先级高于 OR
可以用括号改变优先级
【例 3.38】查询计算机系年龄在20岁以下的学生姓名。
有两个条件,(1)系别为计算机系 (2)年龄为20岁以下
所以用AND连接
SELECT Sname
FROM Student
WHERE Sdept = 'CS' AND Sage < 20;
- ORDER BY字句(排序)
(1)可以按一个或多个属性列排
(2)升序:ASC 降序:DESC 缺省项为ASC
(3)对于空值,排序时显示的次序由具体系统实现来决定
【例 3.39】查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列。
SELECT Sno,Grade
FROM SC
WHERE Cno = '3'
ORDER BY Grade DESC;
【例 3.40】查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列。
SELECT *
FROM Student
ORDER BY Sdept ASC,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.43】是一样哒
【例 3.45】查询学生201215012选修课程的总学分数。
这里需要计算学分总和,所以需要用到Course表
还需要包含学生选修课程,所以需要用到SC表
所以需要在选择之前将Course表和SC表做等值连接SC.Cno = Course.Cno
SELECT SUM(Ccredit)
FROM SC,Course
WHERE Sno = '201215122' AND SC.Cno = Course.Cno;
【例 3.46】GROUP BY字句分组
细化聚集函数的作用对象
(1)如果未对查询结果分组,聚集函数将作用于整个查询结果
(2)对查询结果分组后,聚集函数将分别作用于每个组
(3)按指定的一列或多列值分组,值相等的为一组
【例 3.46】求各个课程号及相应的选课人数。
SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;
【例 3.47】查询选修了3门以上课程的学生学号。
SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(*) > 3;
HAVING字句使用的时候,必须跟着GROUP BY 语句出现,不可单独使用!!!
GROUP BY… HAVING…的作用相当与先根据GROUP BY 分组,再根据HAVING 后面的条件选择。
【例 3.48】查询平均成绩大于等于80分的学生学号和平均成绩。
下面这种写法是❌的,因为WHERE子句中是不能用聚集函数作为条件表达式的!!!
SELECT Sno,AVE(Grade)
FROM SC
WHERE AVG(GRADE) >= 80
GROUP BY Sno;
✔️
SELECT Sno,AVE(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade)>= 90;
HAVING短语与WHERE子句的区别
(1)作用对象不同
WHERE子句作用于基表或视图,从中选择满足条件的元组
HAVING短句作用于组,从中选择满足条件的组。