查询语句SELECT的API可以参照上一篇博文:
SQL 索引的操作 数据查询(1)数据更新
Student表如下:
SC表如下:
比较大小
例3.22:查询计算机科学系全体学生的名单
SELECT Sname
FROM Student
WHERE Sdept = 'CS'
运行结果如图:
例3.23:查询所有年龄在20岁以下的学生姓名及其年龄
SELECT Sname,Sage
FROM Student
WHERE Sage < 20
运行结果如图:
自己换了两种写法,发现是等价的:
SELECT Sname,Sage
FROM Student
WHERE Sage BETWEEN 0 AND 19
SELECT Sname,Sage
FROM Student
WHERE Sage !>19
例3.24:查询考试成绩不及格的学生的学号
SELECT DISTINCT Sno
/*这里我自己写的时候没有加DISTINCT*/
/*因为我自己写的时候,只有一门课程,所以不及格的话,学生的姓名也只会出现一次*/
/*但是实际情况下,不可能只有一门课*/
/*有可能会出现一位学生多门课不及格的情况*/
/*运行就会出现多次这个学生的姓名,因此正常情况下要加DISTINCT*/
FROM SC
WHERE Grade < 60
运行结果如下:
确定范围
主要是运用BETWEEN…AND…和NOT BETWEEN…AND…
例3.25:查询年龄在20~23岁(包括20岁和23岁)之间学生的姓名、系别和年龄
SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage BETWEEN 20 AND 23
运行结果如图:
例3.26:查询年龄不在20~23岁之间学生的姓名、系别和年龄
SELECT Sname,Sdept,Sage
FROM Student
WHERE Sage NOT BETWEEN 20 AND 23
运行结果如图:
确定集合
主要是运用IN,IN可以查找属性值属于指定集合的元祖
例3.27:查询既不属于计算机科学系、数学系、也不是信息系的学生的姓名和性别
SELECT Sname,Ssex
FROM Student
WHERE Sdept NOT IN ('CS','MA','IS');
因为我的表格中只有计算机科学系和信息系的学生,所以查询为空,不展示运行结果了
上述代码等价于,只不过上面是集合的形式,下面是挨个说明:
SELECT Sname,Ssex
FROM Student
WHERE Sdept != 'CS' AND Sdept != 'MA' AND Sdept != 'IS';
IN谓词实际上是多个OR运算符的缩写,所以可写成以下的等价形式
SELECT Sname,Ssex
FROM Student
WHERE Sdept = 'CS' OR Sdept = 'MA' OR Sdept = 'IS';
例3.28:查询计算机科学系、数学系、信息系的学生的姓名和性别
SELECT Sname,Ssex
FROM Student
WHERE Sdept IN ('CS','MA','IS');
在确实集合的时候不能使用 = 来确定关系
比如说 WHERE Sdept IN (**** ); 的时候
就不能说 WHERE Sdept = (****);
字符匹配
谓词LIKE 可以用来进行字符串的匹配,一般语法格式如下:
[NOT] LIKE <匹配字符串> [ESCAPE <换码字符>]
含义是:查找指定的属性列值与<匹配字符串>相匹配的元祖。<匹配字符串>可以是一个完整的字符串,也可以是含有通配符%和_
% 代表任意长度字符串(长度可以为0)
_ 代表任意单个字符
例3.29:查询学号为201911003的学生的详细情况
SELECT *
FROM Student
WHERE Sno LIKE '201911003';
这里的LIKE可以替换为=,因为属性值可以用=连接,又因为属性值是一段字符串,所以可以用LIKE连接
SELECT *
FROM Student
WHERE Sno = '201911003';
例3.30:查询所有姓名开头是伊的学生的姓名、学号和性别
SELECT Sname,Sage,Ssex
FROM Student
WHERE Sname LIKE '伊%';
运行结果如图:
试一下_:
SELECT Sname,Sage,Ssex
FROM Student
WHERE Sname LIKE '伊___';
运行结果如图:
发现二者是等价的,也变相说明这个电脑SQL的字符集是GBK的
例3.31:查询姓王且全名为三个汉子的学生的姓名
SELECT Sname
FROM Student
WHERE Sname LIKE '王__';
例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 '\';
例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必能用=代替,因为NULL只能用IS来连接
例3.37:查询所有有成绩的学生学号和课程号
SELECT Sno,Cno
FROM SC
WHERE Grade IS NOT NULL;
多重条件查询
(以下是在自己电脑的SQL2019下完成的)
主要是运用AND和OR,AND的优先级大于OR
例3.38:查询计算机科学系年龄在20岁以下的学生姓名
SELECT Sname
FROM Student
WHERE Sage < 20 AND Sdept LIKE 'CS';
运行结果如下:
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;
运行结果出现了错误:
根据网上查询到的结果是因为DESC是T-SQL中的语句,在写SQL的时候要尽量避免!
T-SQL关键字
聚集函数
常用的聚集函数:
COUNT(*) 统计元组个数
COUNT([DISTINCT|ALL] <列名>) 统计一列中值的个数
SUM([DISTINCT|ALL] <列名>) 统计一列值的总和(此列必须是数值型)
AVG([DISTINCT|ALL] <列名>) 统计一列值的平均值(此列必须是数值型)
MAX([DISTINCT|ALL] <列名>) 求一列值中的最大值
MIN([DISTINCT|ALL] <列名>) 求一列值中的最小值
例3.41:查询学生总人数
SELECT COUNT(*)
FROM Student;
运行结果如下:
例3.42:查询选修了课程的学生人数
SELECT COUNT(DISTINCT Sno)
FROM SC;
因为在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 = '201215012' AND SC.Cno = Course.Cno;
这里只有课程号和学生选的课程号相等时才能确定其对应的学分
GROUP BY子句
GROUP BY子句将查询结果按某一列或多列的值分组,值相等的为一组
例3.46:求各个课程号及相应的选课人数
SELECT Cno,COUNT(Sno)
FROM SC
GROUP BY Cno;
如果分组后还要求按一定的条件对这些组进行筛选,最终只输出满足指定条件的组,则可以使用HAVING短语指定筛选条件
例3.47:查询选修了三门以上课程的学生学号
SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(*) > 3;
WHERE 作用于基本表
HAVING 作用于组
例3.48:查询平均成绩大于等于90分的学生学号和平均成绩
错误做法:
SELECT Sno,AVG(Grade)
FROM SC
WHERE AVG(Grade) >= 90
GROUP BY Sno;
因为WHERE子句中是不能用聚集函数作为条件表达式!!
正确做法:
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade) >= 90;