SELECT:【例3.29】~【例3.48】
REF:教材3.4“数据查询”的部分例题
1. 在SQLserver上运行,观察运行效果,并把代码写到作业中。
2. 写出自己的理解/收获/心得体会(部分比较复杂的例题,建议增加测试方法和测试数据,举一反三)。
REF:建表&插入数据
作业原地址:作业
书接上回:【数据库】作业5——SQL练习2 - INDEX / INSERT / SELECT
注:因为这个和前一个作业是一起写的,所以也和上个作业情况一样,数据出现了丢失,扫了一下这次作业,没有特别的情况,也没有什么大的问题出现,所以这次作业只交了代码,没有实验截图了。(已经做完了所有例题的前提!!!)
④字符匹配
谓词LIKE可以用来进行字符串的匹配
[NOT] LIKE ‘<匹配串>’ [ESCAPE ‘ <换码字符>’]
其含义是查找指定的属性列值与<匹配串>相匹配的元组。
<匹配串>可以是一个完整的字符串,也可以含有通配符%和 _
%:任意长度(长度可以为0)的字符串。
_ :代表任意单个字符。
【例3.29】查询学号为201215121的学生的详细情况。
SELECT *
FROM Student
WHERE Sno LIKE '201215121';
等价于
SELECT *
FROM Student
WHERE Sno = '201215121';
【例3.30】 查询所有姓刘学生的姓名、学号和性别。
SELECT Sname, Sno, Ssex
FROM Student
WHERE Sname LIKE '刘%';
【例3.31】查询姓"欧阳"且全名为三个汉字的学生的姓名。
SELECT Sname
FROM Student
WHERE Sname LIKE '欧阳_';
注:数据库字符集为ASCII时一个汉字需要两个_;当字符集为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 '\';
⑤涉及空值的查询
【例3.36】某些学生选修课程后没有参加考试,所以有选课记录,但没 有考试成绩。查询缺少成绩的学生的学号和相应的课程号。
SELECT Sno,Cno
FROM SC
WHERE Grade IS NULL;
注:这里的“IS”不能用(=)代替。
【例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;
3.ORDER BY 子句
可以用OREDR BY 子句对查询结果按照一个或多个属性列的升序(ASC)或降序(DESC)排列,默认值为升序。
对于空值,排序时显示的次序有具体系统实现来决定。
【例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;
4.聚集函数
COUNT(*) 统计元组个数
COUNT([DISTINCT|ALL] <列名>) 统计一列中值的个数
SUM([DISTINCT|ALL] <列名>) 计算一列值的总和(此列必须是数值型)
AVG([DISTINCT|ALL] <列名>) 计算一列值的平均值(此列必须是数值型)
MAX([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='201215122' AND SC.Cno=Course.Cno;
注:当聚集函数遇到空值时,除了COUNT(*)外,都跳过空值而只处理非空值。
5.GROUP BY 子句
GROUP BY 子句将查询结果按某一列或多列的值分组,值相等的为一组。
分组后聚集函数将作用与每一个组,即每一组都有一个函数值。
【例3.46】求各个课程号及相应的选课人数。
SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;
【例3.47】查询选修了三门以上课程的学生学号。
SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(*)>3;
注:先用GROUP BY 子句按照Sno分组,再用聚集函数COUNT对每一组计数,HAVING短语给出了选组的条件。
WHERE子句与HAVING短语的区别:作用的对象不同。
WHERE子句:作用域基本表或视图,从中选择满足条件的元组。
HAVING短语:作用于组,从中选择满足条件的组。
【例3.48】查询平均成绩大于等于90分的学生学号和平均成绩。
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade)>=90;
总结:emm和上个作业小情况一样,写作业的时候数据不小心都弄丢了,所以这次没有截图...不过每个例题都做了,代码也是一键一键敲的,这次也还好,没什么特别难的语句,也没碰见什么大问题。
上期传送阵:【数据库】作业5——SQL练习2 - INDEX / INSERT / SELECT
下期传送阵:————
完成时间:55min(仅为写博客时间,用SQL的时间紧接上期作业,未计时)
以上
————(2020.3.15)