接作业五的内容!!!!!
4、字符匹配
谓词LIKE可以用来进行字符串的匹配。
[NOT] LIKE‘<匹配串>’ [ESCAPE '<换码字符>']
<匹配串>可以是一个完整的字符串,也可以含有通配符%和_。其中:
·%(百分号)代表任意长度(长度也可以为0)的字符串。例如a%b表示以a开头,以b结尾的任意长度的字符串。
·_(下横线)代表着任意单个字符。例如a_b表示以a开头,以b结尾的长度为3的任意字符串。
例3.29
查询学号为201215121的学生的详细情况。
SELECT *
FROM Student
WHERE Sno LIKE '201215121';
注意:这里的LIKE相当于等于的意思,如果LIKE后面的匹配串中不含通配符,则可以用=(等于号)运算符取代LIKE谓词,用!=或<>(不等于)运算符取代NOT LIKE谓词。
例3.30
查询所有姓刘的学生的姓名、学号和性别。
SELECT Sname,Sno,Ssex
FROM Student
WHERE Sname LIKE '刘%';
例3.31
查询姓“欧阳”且全名为三个汉字的学生的姓名。
SELECT Sname,Sno,Ssex
FROM Student
WHERE Sname LIKE '欧阳__';
注意:数据库字符集为ASCII时一个汉字需要两个__;当字符集为GBK时只需要一个_.在我的电脑MySQL里应该是GBK字符集,一个汉字只需要一个_
例3.32
查询名字中第二个为“阳”的学生的姓名和学号。
SELECT Sname,Sno
FROM Student
WHERE Sname LIKE '_阳%';
例3.33
查询所有不姓刘的学生的姓名、学号和性别。
SELECT Sname,Sno,Ssex
FROM Student
WHERE Sname NOT LIKE '刘%';
如果用户要查询的字符串本身就含有通配符%或_,这时就要使用ESCAPE '<换码字符>'短语对通配符进行转义了。
例3.34
查询DB_Design课程的课程号和学分。
SELECT Cno,Ccredit
FROM Course
WHERE Cname LIKE 'DB\_Design' ESCAPE '\';
ESCAPE’'表示“\”为换码字符,这样匹配串中紧跟在“\”后面的字符“”不再具有通配符的含义,转义为普通的“”字符。
例3.35
查询以“DB_”开头,且倒数第三个字符为i的课程的详细情况。
SELECT *
FROM Course
WHERE Cname LIKE 'DB\_%i__' ESCAPE '\';
理解,如果所匹配的字符串中本身具有_或者%时,可以在WHERE语句中在_或者%前面加上,在后面再加上ESCAPE ''或者ESCAPE ‘%’,这样做系统就不会把_或者%当成通配符,他只是简单的字符而已。而\只能保证跟在它后面的一个从通配符转义成字符串,简单来说就是一对一关系,一个\只能识别一个通配符
5、涉及空值的查询(IS NULL或者IS NOT NULL)
例3.36
某些学生选修课后没有参加考试,所以有选课记录,但是没有考试成绩。查询缺少成绩的学生的学号和对应的课程号。
SELECT Sno,Cno
FROM SC
WHERE Grade IS NULL; /*分数Grade时空值*/
注意:这里的“IS”虽然表示的是“是”的意思,但是不能用“=”代替。
例3.37
查所有有成绩的学生学号和课程号。
SELECT Sno,Cno
FROM SC
WHERE Grade IS NOT NULL;
6、多重条件查询(AND 或者OR)
逻辑运算符AND和OR可用来连接多个查询条件。AND的优先级高于OR,但用户可以用括号改变优先级。
例3.38
查询计算机科学系年龄在20岁以下的学生姓名。
SELECT Sname
FROM Student
WHERE Sdept='CS' AND Sage<20;
注意:谓语IN实际上可以表示为多个OR运算符的缩写
例如:Sdept IN ('CS','MA','IS') 等效为 Sdept='CS' OR Sdept='MA' OR Sdept='IS'
ORDER BY子句
用户可以用ORDED BY子句对查询结果按照一个或多个属性列的升序(ASC)或降序(DESC)排列,默认值为升序。
例3.39
查询选修了3号课程的学生的学号及其成绩,查询结果按分数的降序排列。
SELECT Sno,Grade
FROM SC
WHERE Cno='3'
ORDER BY Grade DESC;
注意:对于空值要按照具体排列顺序而定。根据MySQL运行结果发现按照升序排列时,空值排到最前面;按照降序排列,空值排在最后
例3.40
查询全体学生情况,查询结果按所在系的系号升序排列,同一系中的学生按照年龄降序排列。
SELECT *
FROM Student
ORDER BY Sdept,Sage DESC;
注意:默认为升序,两个同排列的情况下,先把第一个按照序列排序,在第一个值相同的情况下,在用第二的排列顺序排列,以此类推。
聚集函数
为了进一步方便用户,增强检索功能,SQL提供了许多聚集函数,主要有:
统计元组个数
COUNT(*)
统计一列中值的个数
COUNT([DISTINCT|ALL] <列名>)
计算一列值的总和(此列必须是数值型)
SUM([DISTINCT|ALL] <列名>)
计算一列值的平均值(此列必须是数值型)
AVG([DISTINCT|ALL] <列名>)
求一列值中的最大值
MAX([DISTINCT|ALL] <列名>)
求一列值中的最小值
MIN([DISTINCT|ALL] <列名>)
强调:DISTINCT表示的是删除重复行,ALL或者不指定就是不取消重复值
例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='201215121' AND SC.Cno=Course.Cno;
当聚集函数遇到空值时,除COUNT()外,都跳过空值只处理非空值。COUNT()对元组进行计数,某个元组的一个或部分列取空值不影响COUNT的统计结果。
注意:两表连接时,要用表名1.列名=表名2.列名。
WHERE子句中时不能用聚集函数作为条件表达式的。聚集函数只能用于SELECT子句和GROUP BY中的HAVING子句。HAVING 子句只能跟着GROUP BY 作用于组
GROUP BY子句
GROUP BY子句将查询结果按某一列或多列的值分组,值相等的为一组。分组后聚集函数将作用于每一个组,即每一组都有一个函数值。
**理解:GROUP BY子句是细化聚集函数的作用对象
分组后,分别作用于每个组
分组前,作用于整个查询结果
按照指定的列或多列
**
例3.46
求各个课程号及相应的选课人数
SELECT Cno,COUNT(Sno) COUNT
FROM SC
GROUP BY Cno;
结果为:
分析该语句,是先按照Cno的值分组,具有相同值的为一组,然后根据聚集函数COUNT进行计算,求得每组的人数。
如果分组后还要求按照一定的条件对这些进行筛选,最终只输出满足指定条件的组,则可以用HAVING短语指定筛选条件。
例3.47
查询选修了三门以上上课的学生学号。
SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(*)>3;
分析:先用GROUP BY子句对Sno分组,再用聚集函数对每组进行计数;HAVING短语筛选条件,满足条件被选出。
WHERE子句与HAVING短语的区别在于作用对象不同。WHERE子句作用于基本表或视图,从中选择满足条件的元组,HAVING短语作用于组,从中选择满足条件的组。
例3.48
查询平均成绩大于或等于90分的学生学号和平均成绩。
错误示范:
SELECT Sno,AVG(GRADE)
FROM SC
WHERE AVG(GRADE)>=90
GROUP BY Sno ;
再次强调:聚合函数不应出现在 WHERE 子句中,除非该聚合函数位于 HAVING 子句或选择列表所包含的子查询中,并且要对其进行聚合的列是外部引用。
正确表达:
SELECT Sno,AVG(GRADE)
FROM SC
GROUP BY Sno
HAVING AVG(GRADE)>=90;
参考文献:
【1】王珊 萨师煊.数据库系统概论(第5版).高等教育出版社
用了一下午和一晚上把作业五和作业六写完,写完之后还是很放松的,在写的过程中又把上课学的东西又复习了一遍,在此期间,还把在课上不太懂聚集弄懂了,有更加加深了对于部分单词,语句的记忆。这真的是个很漫长的工作,把课本又细读了一遍,收获颇丰。再次期间也有许多小问题要注意,比如字母大小写问题,中英符号,空格问题,这些问题都值得注意,写完之后脑子有点凌乱,先就这样吧,让我们下次作业再见。