1-6 数据查询
u      了解SQL查询的基本类型,掌握SQL查询的基本语法内涵
u      学习数据查询属性的更名运算,消除取值重复的行
u      学习数据条件查询,包括:比较条件查询,确定范围的条件查询,确定集合的条件查询,字符匹配的条件查询,涉及空值的条件查询,选取前N行的数据,多重条件查询
u      掌握集函数以及如何使用集函数对查询结果分组
u      学习多表连接查询,包括:比较连接查询,自然连接查询
u      学习单表的自身连接查询
u      学习多表嵌套查询
u      学习SQL86SQL92语法的异同点,掌握SQL86SQL92实现内连接查询
u      学习外连接,包括:左外连接和右外连接查询
u      学习SQL交叉与无限制连接查询
u      学习SQL集合并与交的查询
u      了解关系代数中近似除与关系整除的SQL查询方法,近似除与关系整除的查询
u      集合差的SQL查询
u      了解全称谓词查询   
1-6-1 查询概述
查询是建立数据库最为重要的目的,也是SQL最为广泛和复杂的应用。查询的类型概括来说可以包括下面的类型:
1. 单表查询
可以包含:按列查询、查询经过计算的值、消除取值重复的行、条件查询、对查询结果排序、使用集函数、对查询结果分组
2. 连接查询
等值与非等值连接查询、自身连接、复合条件连接
3. 嵌套查询
带有IN谓词的子句查询、带有比较运算符的子查询
4. 集合查询
查询的一般格式为:
SELECT [ALL|DISTINCT] <目标列表达式> [,<目标列表达式>]…
FROM <表名或视图名> [,<表名或视图>]…
[WHERE<条件表达式>]
[GROUP BY <列名1> [HAVING<条件表达式>]]
[ORDER BY <列名2> [ASC|DESC]];
Select子句指定要显示的列,from子句列出查询的对象表,where为查询的条件,group by表示分组,order by表示排序。
1-6-2 基本表查询
实验1:基本表的查询
--1:查询指定列
SELECT Sno,Sname FROM Student;
--2SELECT Sname,Sno,class FROM Student;
--3:查询全部列
SELECT * FROM Student;     
--等价于:SELECT Sno,sname,Ssex,Sage,class FROM Student;
这里需要注意的是,“*”:表示所有的属性目标列可以为列名,* ,算术表达式,聚集函数
实验2:更名运算
更名运算的基本格式是:old_name as  new_name,为关系和属性重新命名,可出现在selectfrom子句中,当然关键词as是可选项目。
--1:给出所有老师的姓名、所纳税额及税后工资额
   select TNAME,Salary*0.05 as ’纳税’,Salary *0.95 as ’实际收入  
   from   teacher
--2:查询每个学生的姓名和年龄
   SELECT Sname,year(getdate())-year(birthday) as ’年龄’ FROM Student
实验3:消除取值重复的行
在某些查询中,会出现查询的数据重复出现的现象。如图1-35所示,当查询sc表的时候,如从SC表查询学号sno (SELECT Sno FROM SC),就会出现第一次的查询结果,95001学号重复,如果使用了distinct参数(SELECT DISTINCT Sno FROM SC),则将去掉重复的信息。
 

 

1-6 数据查询(上)——基础查询_职场

 1-35 使用distinct去除重复行

1-6-3 条件查询
SQL的查询语句中,where语句后面出现的是条件查询,条件查询的基本内容见图1-36所示。
 

1-6 数据查询(上)——基础查询_职场_02

1-36 条件查询的关键词
实验1:比较条件查询
--1:查95033班全体学生的名单
   SELECT Sname FROM Student WHERE class=‘95033’
--2:查所有年龄在20岁以下的学生姓名及其年龄
    SELECT Sname,Sage FROM Student WHERE year(getdate())-year(birthday)<20
    2也可以用下面的语句实现同样的功能:
    SELECT Sname,Sage FROM Student
    WHERE NOT year(getdate())-year(birthday)>=20
--3:查考试成绩有不及格的学生的学号
    SELECT DISTINCT Sno FROM Course WHERE Grade<60;
实验2:确定范围的条件查询
Between ..and…:是判断表达式的值是否在某范围内,其确定的是查询的集合范围。
--1:查询年龄在2023岁之间的学生的姓名、系别、和年龄
SELECT Sname,class, year(getdate())-year(birthday) as 年龄
FROM Student
WHERE year(getdate())-year(birthday) BETWEEN 20 AND 23;
--2:查询年龄不在2023岁之间的学生姓名、系别和年龄
SELECT Sname, class,Sage
FROM Student
WHERE year(getdate())-year(birthday) NOT BETWEEN 20 AND 23;
实验3:确定集合的条件查询
判断表达式的值是否在子查询的结果中,关键词为in或者no in
--1:查询‘95031’’95033’班级的学生
SELECT Sname,Ssex FROM Student WHERE class IN (‘95031’,’95033’)
--2:查询非‘95031’班级的学生
SELECT Sname,Ssex FROM Student WHERE class NOT IN (‘95031’)
实验4:字符匹配的条件查询
字符串匹配使用的谓词为LIKE,其一般语法格式为:[NOT] LIKE ‘<匹配串>’ [‘ESCAPE’ <换码字符>]。使用like关键词的含义是查找指定的属性列值与<匹配串>相匹配的元组,<匹配串>可以是一个完整的字符串,也可以含有通配符%_。通配符含义为:
q        “%”:匹配零个或多个字符;
q        _:匹配任意单个字符;
q        Escape:定义转义字符,以去掉特殊字符的特定含义,使其被作为普通字符看待。如escape “\”,定义 \ 作为转义字符,则可用\%去匹配%,用\_去匹配_。
--1:查找姓刘的学生的姓名,年龄,性别
SELECT Sname,Sno,Ssex FROM Student WHERE Sname LIKE ‘%’
--2:查询课程名称以”db_”开头的所有课程情况
Select * from course where cname like ‘db\_%’ escape ‘\’
--3:查询课程名称以”db_”开头,且倒数第3 个字符为I的课程和详细情况。
Select * From course Where cname like ‘db\_%I__’escape ‘\’
--注意:Escape为转义符。表示\后面的字符_不再具有通配符的含义。
实验5:涉及空值的条件查询
空值意味着不知道,没有的意思,对于空值需要注意事项包括:
q        is [not] null之外,空值不满足任何查找条件
q        如果null参与算术运算,则该算术表达式的值为null
q        如果null参与比较运算,则结果可视为false。在SQL-92中可看成unknown
q        如果null参与聚集运算,则除count(*)之外其它聚集函数都忽略null
--1:查缺少成绩的学生的学号和相应的课程号
SELECT Sno,Cno FROM SC WHERE Grade IS NULL;
--2:查所有有成绩的记录的学生学号和课程号
SELECT Sno,Cno FROM SC WHERE Grade IS NOT NULL;
实验6:选取前N行的数据
可以使用TOP N 来选取前N行的数据,但是一般最好配合order by 语句进行排序查找。
--1:查询薪酬排名前3名的教师
select top 3 * from teacher order by salary
实验7:多重条件查询
SQL的查询语句中,如果where语句后面出现的两个以上条件的查询就是多重条件查询。
--1:查95031班年龄在20岁以下的学生姓名
SELECT Sname FROM Student
WHERE class=‘95031’ AND year(getdate())-year(birthday)<20;
--2:查询95031班或者95033班的学生姓名及性别
SELECT Sname,Ssex FROM Student WHERE class =’95031’ OR class =’95033’
--2语句下面语句具有相同的执行结果:
SELECT Sname,Ssex FROM Student WHERE class IN (‘95031’, ‘95033’)
 注意:
在多重条件查询中,经常使用的逻辑关系谓词是“与、或、非”,对应的是and/or/not,其优先级为Not优先级高于and,and优先级高于or
实验8:对查询结果排序
排序的关键谓词是order by,在SQL的查询语句中出现在最后,如果是升序可以指定谓词Asc,如果是降序为Desc,如果不添默认为Asc
--1:查询选修了课程166号的学生学号及成绩,并按成绩升序排列
SELECT Sno,Grade FROM SC WHERE Cno=‘166’ORDER BY Grade Asc;
--2:查询全体学生情况,查询结果按所在系升序排列,对同一班级中的学生按生日降序排列
SELECT * FROM Student ORDER BY class,birthday DESC;
实验9:使用集函数
集函数是SQL中规定好的处理集合数据算术运算的函数,主要包括以下几个:
q        COUNT [DISTINCT|ALL] *统计元组个数
q        COUNT [DISTINCT|ALL] <列名>统计一列中值的个数
q        SUM [DISTINCT|ALL] <列名>)计算一列值的总和
q        AVG[DISTINCT|ALL] <列名>)计算一列值的平均值
q        MAX[DISTINCT|ALL] <列名>)求一列值中的最大值
q        MIN[DISTINCT|ALL] <列名>)求一列值中的最小值
--1:查询学生总人数
 SELECT COUNT(*) FROM Student;
--2:查询选修了课程的学生人数
SELECT COUNT(DISTINCT Sno) FROM SC;
--3:计算1号课程的学生平均成绩
SELECT AVG(Grade) FROM SC WHERE Cno=‘166’;
--4:查询学习166号课程的学生最高分数
SELECT MAX(Grade) FROM SC WHERE Cno=‘166’;
 注意:
空值对于集函数运算而言有着特殊的含义,如果出现对含有空值属性的统计,则空值选项不参与统计工作。如图1-37中的表SC,我们看看不同的统计在有空值参与的情况下的结果。
--5select sum(G) from SC --结果为350
--6select avg(G) from SC --结果为87.5
--7select    count(*) from SC --结果为6
--8select    count(G)   from SC --结果为4

1-6 数据查询(上)——基础查询_职场_03 

1-6 数据查询(上)——基础查询_职场_04

                 
1-37 基本表SC中成绩G的空值计算              1-38 基本表SC不同分组统计结果
实验10:对查询结果分组
对查询结果进行分组的命令是group by关键词,该谓词将表中的元组按指定列上值相等的原则分组,然后在每一分组上使用聚集函数,得到单一值;having则对分组进行选择,只将聚集函数作用到满足条件的分组上,案例如图1-38所示。其基本表述如下:
group by 列名 [having 条件表达式]
--1:列出每个学生的平均成绩
 SELECT AVG(G) FROM SC group by sno
--2:列出每门课程的平均成绩
SELECT AVG(G) FROM SC group by cno 
--例子12的基本逻辑可以见图1-45所表述的逻辑关系。
--3:查询信息系选修了3门以上课程的学生的学号
SELECT Sno FROM SC GROUP BY Sno HAVING COUNT(*) >3;
--4:列出每一年龄组中男学生(超过50人)的人数
   select sAGEcount(Sno) from Student where   sSEX = ‘M’
   group by sAGE having count(*) > 50
问题:如果有一SQL问题列出及格的学生的平均成绩,下面两个答案那个正确呢?
--答案1
select    SNOavg(grade) from SC group by SNO having min(grade) >= 60
--答案2
select    SNOavg(grade) from SC wher grade>=60 group by SNO