接着上次的查询,上次简单的叙述啦单表查询, 这次主要涉及一些更加重要的查询。主要是练习书上的例题。
首先附上之前学过的select格式语句。
查询语句的一般格式为:
SELECT [ALL|DISTINCT]<目标列表达式>[,<目标列表达式>]...
FROM <表名或视图名>[,<表名或视图名>...]|(<SELECT 语句>)[AS]<别名>
[WHERE<条件表达式>]
[GROUP BY <列名1>[HAVING<条件表达式>]]
[ORDER BY <列名2>[ASC|DESC]];
一、选择表中的若干列
select子句的<目标表达式>不仅可以是表中的属性列,也可以是算术表达式,还可以是字符串常量、函数等。
(3)查询经过计算的值
【例 3.19】查询全体学生的姓名及其出生年份。
select Sname,2014-Sage
from Student;
【例 3.20】查询全体学生的姓名、出生年份和所在的院系,要求用小写字母表示系名。
select Sname,'Year of Birth',2014-Sage,lower(Sdep)
from Student;
enmmm,这里没有列名,那就用别名弄吧。
select Sname NAME,'Year of Birth:' BIRTH,2014-Sage BIRTHDAY,lower(Sdep) DEPARTMENT
from Student;
二、选择表中的若干元祖
(1)消除取值重复的列
两个不相同的元祖投影到指定的某些列上后,可能会出现重复的列,可以用DISTINCT消除他们。
【例 3.21】查询选修了课程的学生学号。
select Sno
from SC;
其中有许多重复的列,加上DISTINCT语句后:
select distinct Sno
from SC;
如果没有指定DISTINCT关键词,则默认为ALL,即保留结果表中取值重复的行。
(2)查询满足条件的元祖
查询满足指定条件的元祖可以通过WHERE子句实现。
①比较大小
【例 3.22】查询计算机科学系全体学生的名单。
select Sname
from Student
where Sdep='CS';
enmmm,如果数据库里面人数多的情况下,我们可以在查询的目标上建立一个索引,提高查询速度。但是如果学生较少,索引查找不一定能提高查询效率,适当做出一些选择。
【例 3.23】查询所有年龄在20岁以下的学生姓名及其年龄。
select Sname,Sage
from Student
where Sage < 20;
【例 3.24】查询学生成绩不及格的学生的学号。
select DISTINCT Sno
from SC
where Grade<60;
②确定范围
谓词between…and…和betwee…not and…用来查找属性值在或不在指定范围内的元祖。and前为下限,and后为上限。
【例 3.25】查询年龄在20~23岁(包含20岁及23岁)之间的学生姓名,系别和年龄。
select Sname,Sdep,Sage
from Student
where Sage between 20 and 23;
【例 3.26】查询年龄不在20和23岁之间的学生姓名、系列和年龄。
select Sname,Sdep,Sage
from Student
where Sage not between 20 and 23;
③确定集合
谓词IN可以用来查找属性值属于指定集合的元祖。
【例 3.27】查询计算机科学系(CS)、数学系(MA)和信息系(IS)学生的姓名和性别。
select Sname,Ssex
from Student
where Sdep in('CS','MA','IS');
【例 3.28】
select Sname,Ssex
from Student
where Sdep not in('CS','MA','IS');
④字符匹配
谓词like可以用来进行字符串的匹配。
一般语法为:
[not] like '<匹配符>' [escape'<换码字符>']
其含义是查找指定的属性列值与<匹配串>相匹配的元祖。匹配串可以是一个完整的字符串,也可以含有通配符%和下横线。
%代表任意长度的字符串。
-下横线代表任意单个字符。
为啦下面操作查询能查到一些可以比对的信息,我们分别在表中分别添加几个数据。
【例 3.29】査询学号为201215121的学生的详细情况。
select *
from Student
where Sno like '201215121';
--或者
select *
from Student
where Sno = '201215121';
当 like 后面的匹配串中不含有通配符号,可以用 = 代替 like ,用 != 或 <> 运算符取代not like。
【例 3.30】 査询所有姓刘的学生的姓名、学号和性别。
select Sname, Sno , Ssex
from Student
where Sname like '刘%';
【例 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;
--尝试用等号判断一下null:
select Sno , Cno from SC where Grade = null;
显然,不能用 = 来判断 NULL 值。
【例 3.37】 査所有有成绩的学生学号和课程号。
select Sno , Cno from SC where Grade is not null;
-- 用!= 来判断不行
select Sno , Cno from SC where Grade != null;
显然,也不可以用 != 来判断NULL值。
【例 3.38】 查询计算机科学系年龄在20岁以下的学生姓名。
select Sname
from Student
where Sdep = 'CS' and Sage < 20;
三、ORDER BY 子句
【例 3.39】 査询选修了 3号课程的学生的学号及其成绩,査询结果按分数的降序排列。
select Sno , Grade
from SC
where Cno = '3' order by Grade desc;
试一下升序的时候,看NULL是否在前。
select Sno , Grade
from SC
where Cno = '3' order by Grade asc;
对于空值,排序时现实的次序由具体系统实现来决定。所以可以看出降序时NULL在后,升序时NULL在前!!!
【例 3.40】 査询全体学生情况,査询结果按所在系的系号升序排列,同一系中的学生按年龄降序排列。
select *
from Student
order by Sdep asc, Sage desc;
四、聚集函数
为啦进一步方便用户,增强检索功能,SQL提供啦许多聚集函数。
COUNT (*) --统计元祖个数
COUNT ([DISTINCT|ALL] <列名>) --统计一列中植的个数
SUM ([DISTINCT|ALL] <列名>) --计算一列值的总和
AVG ([DISTINCT|ALL] <列名>) --计算一列值的平均值
MAX ([DISTINCT|ALL] <列名>) --求一列之中的最大值
MIN ([DISTINCT|ALL] <列名>) --求一列值中的最小值
如果指定DISTINCT短语,则删去重复值。若没有指定DISTINCT短语,默认为ALL,则表示不删除重复值。
【例 3.41】査询学生总人数。
select count(*)
from Student;
【例 3.42】 査询选修了课程的学生人数。
select count(distinct Sno)
from Student;
【例 3.43】 计算选修1号课程的学生平均成绩。
select avg(Grade)
from SC
where Cno = '1';
【例 3.44】 査询选修1号课程的学生最高分数。
select max(Grade)
from SC
where Cno = '1';
【例 3.45】 査询学生201215121 选修课程的总学分数。
select sum(Ccredit)
from SC,Course
where Sno = '201215121' and SC.Cno = Course.Cno;
当聚集函数遇到控制时,除COUNT(*)外,都跳过空值而只处理非空值。某些元祖的一个或多个列取空值不影响COUNT的统计结果。
注意:WHERE子句是不能用聚集函数作为条件表达式的。聚集函数只能用于 SELECT 子句和 GROUP BY 中的 HAVING 子句。
enmmm,这节课实验例题有点小多!!!GROUP BY还没讲完,到下次一起弄吧。