这是一些单表查询的例题的练习。
【3.29】
SELECT *
FROM Student
WHERE Sno LIKE '201215121';
等价于:
SELECT *
FROM Student
WHERE Sno = '201215121 ';
使用LIKE可以用来进行字符串的匹配,例如 LIKE ‘<匹配串>’ ,它是为了查找指定的属性值与<匹配串>相匹配的元组。 LIKE 与 = 等价,如图,测试结果一致
【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 '刘_';
结果(刘后有一个下划线):
_ (下横线) 代表任意单个字符,数据库字符集为ASCLL时一个汉字需要两个_,GBK一个汉字则需要一个 _
在本机测试中可以看到, 刘_ 显示的信息有:刘,刘a,刘晨;刘__显示的信息有:刘,刘a,刘晨,刘aa,刘一一。故得出结论:一个汉字只需要一个下划线。
但是下划线代表的单个字符可以为空吗?
测试案例中可以看到 刘_ 和 刘__ 的查询结果中有 刘 ,这说明后置的下划线是可以为空的。但是前置的和中置的下划线不能为空。(大概)
例子:
SELECT Sname,Sno
FROM Student
WHERE Sname LIKE '刘_a';
--
SELECT Sname,Sno
FROM Student
WHERE Sname LIKE '__a';
结果:
我的测试数据里有 刘a 和 刘aa 和 a,刘_a 的查询结果只有 刘aa,说明中置的下划线不能为空;__a 的查询结果只有 刘aa,说明前置的也不能为空。好奇怪啊。。。
【3.32】
SELECT Sname,Sno
FROM Student
WHERE Sname LIKE '_a';
【3.33】
SELECT Sname, Sno, Ssex
FROM Student
WHERE Sname NOT LIKE '刘%';
NOT LIKE 就是查询与 LIKE 相反的那些数据。比如,LIKE '刘%'是查询姓刘的学生,NOT LIKE ‘刘%’ 就是查询不姓刘的学生。
【3.34】
SELECT Cno,Ccredit
FROM Course
WHERE Cname LIKE 'DB\_Design' ESCAPE '\' ;
查询DB_Design课程的课程号和学分。
当我们要查询的字符串中本身就有_或者%,为了把他们区分开,就要用ESCAPE ‘ <换码字符>’ 对通配符进行转义,表示紧跟在\后面的字符只是普通字符。
【3.35】
SELECT *
FROM Course
WHERE Cname LIKE 'DB\_%i__' ESCAPE '\' ;
查询以"DB_"开头,且倒数第3个字符为 i的课程的详细情况。
但是我认为,i不一定是倒数第三个字符。就好像是上边例子里说的,后置的下划线可以为空,我的查询结果是:
【3.36】
SELECT Sno,Cno
FROM SC
WHERE Grade IS NULL;
IS NULL
“ IS 不能写为 = ”,查询Grade为NULL 的。用=的话结果和IS是不同的。
【3.37】
SELECT Sno,Cno
FROM SC
WHERE Grade IS NOT NULL;
IS NOT NULL 不为空,和上例IS NULL 正好相反。
【3.38】
SELECT Sname
FROM Student
WHERE Sdept= 'CS' AND Sage<20;
AND ,与,用于连接多个查询条件。OR ,或。
IN其实是多个OR的运算符的缩写。
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 ';
【3.39】
SELECT Sno, Grade
FROM SC
WHERE Cno= '3'
ORDER BY Grade DESC;
按照成绩进行降序排列。
可以看到,这段语句比之前的多出了一行 ORDER BY,它的意思是按照排序,就是将查找出的数据按照一个属性进行排序。ASC为升序,DESC为降序,没有说明则为ASC。
结果:
将降序改为升序ASC,得出结果:
【3.40】
SELECT *
FROM Student
ORDER BY Sdept, Sage DESC;
当ORDER BY 后面有两个属性列时,指的是先按第一个属性列进行排序,第一个属性值相同的元组们再按照第二个属性列进行排序,将结果显示出来。
【3.41】
SELECT COUNT(*)
FROM Student;
查询学生总人数。
COUNT(*)是指查询有多少元组(行)。学生表多少行就是学生数。
【3.42】
SELECT COUNT(DISTINCT Sno)
FROM SC;
查询选修了课程的学生人数。
SC表不同于学生表,学生表有多少元组,就有多少学生,但是课程表中却不是如此,一个学生可以选多门课,对应的元组不止一个。这时用COUNT(DISTINCT Sno),统计一列中值的个数,这里统计Sno值得个数,也就是学生的个数。
【3.43】
SELECT AVG(Grade)
FROM SC
WHERE Cno= '1';
AVG(列名)计算一列值的平均值。这里是计算Cno=1的成绩的平均值。
【3.44】
SELECT MAX(Grade)
FROM SC
WHERE Cno='1';
MAX(列名)计算一列中的最大值。这里是计算Cno=1的元组成绩的最大值。
【3.45】
SELECT SUM(Ccredit)
FROM SC,Course
WHERE Sno='201215012' AND SC.Cno=Course.Cno;
SUM(列名),计算一列值的总和。
【3.46】
SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;
求各个课程号及相应的选课人数。
GROUP BY 是分组的意思,按照GROUP BY 后面的列名进行分组,值相等的分成一组。COUNT(列名)是上面用来查询有多少行的。
【3.47】
SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(*) >3;
HAVING 是作用于组上,记录有多少个组。它要跟着GROUP BY。
查询选修了3门以上课程的学生学号。
【3.48】
SELECT Sno, AVG(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade)>=90;
查询平均成绩大于等于90分的学生学号和平均成绩。
这里注意,这种是不对的:
SELECT Sno, AVG(Grade)
FROM SC
WHERE AVG(Grade)>=90
GROUP BY Sno;
--聚合不应出现在 WHERE 子句中,除非该聚合位于 HAVING 子句或选择列表所包含的子查询中,并且要对其进行聚合的列是外部引用。
WHERE 后面是不可以跟诸如COUNT ,SUM,AVG之类的聚集函数。
HAVING短语与WHERE子句的区别:作用对象不同。WHERE子句作用于基表或视图,从中选择满足条件的元组;HAVING短语作用于组,从中选择满足条件的组。
自己动手练习例题确实会高效一点,上课听的时候就很容易遗忘,就感觉风过无痕。
而且我觉得上网课录视频效率特别好,比在教室上课要好很多,上课我其实经常走神,好多都漏听,有视频就可以反复看,不会遗漏知识点。
做题时间,总时间是两个半小时多。包括看着电脑发呆,不知道想什么的时候,喝口水啥的,感觉时间浪费的挺快的。所以主要认真做题的时候应该就俩小时吧,差不多。