数据查询 SELECT(1)
单表查询
主要技术:select子句、重复元组处理、from子句、where子句、别名运算、字符串操作、元组排序操作、集合操作、分类汇总、空值处理等。
基本结构:
select A1 , A2 , … , An from r1 , r2 , … , rm where P ;
select语句的一般格式:
select [all|distinct]<目标列表达式> [别名][,<目标列表达式> [别名]] …
from <表名或视图名>[别名][, <表名或视图名>[别名]]…
|(select语句)[as]<别名>
[where <条件表达式>]
[group by <列名1>[having<条件表达式>]]
[order by <列名21>[asc|desc][, <列名22>[asc|desc] …];
select子句
目标列形式:可以为列名,* ,算术表达式,聚集函数。
“*”:表示“所有的属性”。
--例. 查询所有学生的基本信息。
select * from student;
-- 例. 给出所有学生的姓名及出生年份
select sname, 2019-sage from student;
重复元组处理
语法约束
缺省为保留重复元组,也可用关键字all显式指明。若要去掉重复元组,可用关键字distinct或unique指明。
--示例: 找出所有选修课程的学生。
select distinct Sno from SC;
from子句
格式: from <表名列表>[<视图列表>][<子查询>]
注:当select目标列取自多个表时,在不混淆的情况下可以不用显式指明来自哪个关系。
--示例1: 找出成绩低于80分的学生的姓名、性别、系别。
select Sname , Ssex , Sdept from student , sc
where grade < 80 and student.sno = sc.sno ;
--示例2: 查询选修了“数据库”课程的学生的学号及姓名.
select student. sno,sname
from student,sc,course
where student.sno=sc.sno and sc.cno = course.cno and cname ='数据库';
where子句
语法格式:
where <条件表达式>
注:[not] between…and:判断表达式的值是否在某范围内。
--示例1: 列出成绩在80~90之间的学生学号。
select sno from sc
where grade between 80 and 90 ; //含80或90分
--示例2: 列出成绩不在80~90之间的学生学号。
select sno from sc
where grade not between 80 and 90 ; //不含80或90分
别名运算
格式 : old_name [as] new_name
功能:为关系、目标列或表达式指定别名,通常在select和from子句中使用。注:as可选。
select sname as 姓名, 2019-sage as 出生年份 from student ;
字符串操作
格式: 列名 [not] like ‘匹配串’ [escape ‘转义字符’]
功能:找出属性值(字符型)满足给定匹配串条件的元组。
通配字符匹配规则:
“%” :匹配零个或多个字符; “_”:匹配任意单个字符。
“[a-b]”: 匹配区间内的一个字符; “[^c]”: 匹配非c字符。
转义(换码)字符:去掉特殊字符的特定含义,使其被作为普通字符看待。
如 用\%去匹配%,用\_去匹配_,用\ \去匹配 \ 。但转义字符’\’必须用escape定义:escape ’\’
--示例:查询姓“张” 的学生的基本信息。
select * from student where sname like '张%' ;
--示例
--查询所有学号末尾数字不包括1或 3的学生基本信息。
select * from student where sno like '%[^1^3]' ;
--查询所有学号末尾数字位于1~3之间的学生基本信息。
select * from student where sno like '%[1-3]' ;
--查询以“DB_”开头,且倒数第三个字符为i的课程的详细情况。
select * from course where cname like 'DB\_%i_ _' escape ' \';
--列出名称中含有4个字符以上,且倒数第3个字符是d,倒数第2个字符是_的系的所有信息。
select * from student where sname like '%_d\_ _' escape ' \';
元组排序操作
格式:order by 列名 [asc | desc]
功能:按列名值的大小对元组进行升序(asc)(默认)或降序(desc)排列。
示例:按系名升序列出学生姓名、所在系名,同系学生再按姓名降序排列。
select sname, sdept from student
order by sdept asc, sname desc ;
集合操作
集合并:union
集合交:intersect (SQL Server2000不支持, 2005支持)
集合差: except (SQL Server2000不支持, 2005支持)
说明:集合操作自动去除重复元组,如果要保留重复元组,必须用all关键词指明, 即union all。
--示例:求选修了1或2号课程的学生号。
select SNO from SC where CNO ='1'
union
select SNO from SC where CNO ='2' ;
--求至少选修了1和2号课程的学生号。
select SNO from SC where CNO ='1'
intersect
select SNO from SC where CNO ='2';
--求选修了2号而没有选1号课程的学生号。
select SNO from SC where CNO ='2'
except
select SNO from SC where CNO '1';
分类汇总
分组子句: group by 列名 [having 条件表达式]
功能:将表中的元组按指定列上的值相等的原则分组,然后在每一分组上使用聚集函数,得到单一值。having 则对分组进行选择,只将聚集函数作用到满足条件的分组上。
聚集(汇总)函数
平均值:avg;最小值:min; 最大值:max;
求和:sum; 记数:count
--示例:求选修了3门以上课程的学生学号。
select sno from SC
group by sno having count (* )>3;
--示例
--列出每门课程的最高、最低、平均分。
select CNO, max(Grade), min(Grade), avg(Grade)
from SC
group by CNO ;
--列出所选课程都及格的学生的平均成绩。
select SNO,avg(Grade) from SC
group by SNO
having min(Grade) >= 60 ;
空值处理
空值测试: is [not] null
测试指定列的值是否为空值。
--示例: 找出先行课号为空的课程名。
select cname from course
where cpno is null ;
--不能写成 where Grade=null 或 where Grade='
注意事项
除is [not] null之外,空值不满足任何查找条件。
如果null参与算术运算,则该算术表达式的值为null。
如果null参与比较运算,则结果可视为false。(在SQL-92中可看成unknown。)
如果null参与聚集运算,则除count(*)之外其它情况都忽略null而只处理非空值。
-- 例:若选修1号课程的学生有3人,且有1人成绩为null, 则
select avg(grade) from SC where cno='1';--只求2人平均成绩.
select count(*) from SC where cno='1';-- 结果为3.
select count(grade) from SC where cno='1';-- 结果为2.