USING使用
FROM TEAMS INNER JOIN PLAYERS ON TEAMS.PLAYERNO = PLAYERS.PLAYERNO
FROM TEAMS INNER JOIN PLAYERS USING(PLAYERNO)
聚合函数与分组数据
聚合函数
数据分组
前面提到的SQL函数,其实都是行函数。所谓行函数就是作用在每条记录上的函数。本章将介绍列函数,它们都是用于统计汇总数据。除列函数以外,本章还将介绍数据分组的方法,即Group By 子句的用法。在实际应用中,统计汇总和数据分组会经常被放在一起使用。
使用 count 函数求记录个数
count 语法
count ( 列名 )
例:统计student表中的学生人数
select count ( * ) as 总人数 from student
例:统计没有邮箱的人数
select count ( * ) as 没有邮箱的人数 from student where mail is null
使用 sum 函数求和
语法:
sum ( 列名 )
例:计算wj2内 jihe 的总成绩
select sum ( jihe ) as 几何成绩 from wj2
使用 avg 函数求某字段的平均值
语法:
avg ( 列名 )
例:求 wj2 表中 jihe 的平均值
select avg ( jihe ) as 几何成绩平均值 from wj2
使用 max 、min 函数求最大、最小值
语法:
max ( 列名 )
min ( 列名 )
例:求wj2表中几何的最高成绩和最低成绩
select max ( jihe ) as 几何最高成绩 , min ( jihe ) as 几何最低成绩 from wj2
数据分组(group by)
group by 子句用来分组数据,首先必须了解分组是根据指定字段的不同值划分的。例如,性别字段只只有2种值,因此,如果按性别字段分组数据就会产生两个数组;又例如,假设所属院系字段值中有5种不同的值,则如果按所属院系分组就会产生5个组等。
例:student表,按所属院系分组
select 所属院系
from student
group by 所属院系
聚合函数与分组配合使用
count ( * ) 与 group by 的配合使用
例:student 表,按所属院系分组,并显示人数
select 所属院系,count(*) as 各院系人数
from student
group by 所属院系
查询数据的直方图
直方图是表示不同实体之间数据相对分布的条状图,在一个查询语句中使用group by 子句,不仅可以查询数据,还可以格式化数据生成图表。
例:从student表中,查询一个表示每个院系学生人数的直方图
select 所有院系 ,
replicate ( ' = ' , count ( * ) * 3 ) as 人数对比图
from student
group by 所属院系
排序分组结果
例:在student表中,统计每个院系的学生人数,并按学生人数降序排序
select 所属院系,count(*) as 人数
from student
group by 所属院系
order by count(*) desc
反转查询结果
有时,执行查询语句后得到的数据虽然正确元误,但是当人们查看时会很不方便
例:从student表中,查询每个院系的男生人数和女生人数
select 所属院系,性别,count(*) as 人数
from student
group by 所属院系,性别
order by count(*) desc
上面的查询结果,虽然将统计数据查询出来了,但并不是人们习惯的统计样式。那么人们习惯的统计样式又是什么样的呢?
例:上一个例子中的习惯样式
select 所属院系,
count ( case
when 性别 = '男' then 1
else null
end ) as 男生人数 ,
count ( case
when 性别 = '女' then 1
else null
end) as 女生人数
from student
group by 所属院系
使用 having 子句设置分组查询条件
有时,人们只希望查看想要的分组的统计信息,而不是所有分组的统计信息。例如只想查看软件工程和计算机硬件的总人数。这时就需要把其它的系过滤掉
例:在student 表中,统计软件工程系和计算机硬件系的人数,并按学生人数排序
select 所属院系 , count ( * ) as 人数
from student
group by 所属院系
having 所属院系 in ( ' 软件工程 ' , ' 计算机硬件 ' )
order by count ( * )
例:统计Score表中,考试总成线大于450分的学生的信息
select 学号 , sum(考试成绩) as 考试总成绩
from score
group by 学号
having sum(考试成绩)>=450
order by 考试总成绩 desc
第11章
多表连接查询
将数据存储在多个不同表的原因
范式
连接查询
高级连接查询组合查询
多表连接查询是SQL语言最强大的功能之一。它可以在执行查询时动态地先将表连接起来,然后从中查询数据。本章将介绍多表连接查询的相关内容,同进介绍组合查询的用法。
范式
第一范式:
第一范式是关系数据库的底线,要想成为关系数据库则必须满足第一范式,第一范式的内容为,记录的第一个分量都是不可分割的基本数据项。
第二范式:
要满足第二范式,首先必须满足第一范式,即满足第一范式是满足第二范式的前提条件,其次,第二范式增加的要求是每一个非主属性要完全函数依赖于码。
第三范式:
第三范式是在满足第二范式的基础上,增加了每一个非主属性都不传递依赖于码的要求。
连接查询
无连接规则连接
无连接规则连接后得到的结果是两个表中的每一行都互相连接,即结果为笛卡儿积。
语法:
select *(或字段列表)
from 表名1,表名2
有连接规则连接
有连接规则连接,其实就是在无连接规则的基础上,加上Where子句指定连接规则的连接方法。
语法:
select *(或字段列表)
from 表名1,表名2
Where 连接规则
例:将T1和T2表正确连接的语句如下
select *
from T1,T2
where T1.职工号=T2.职工号
使用两表连接查询数据
例:查询名为“张三”的学生的所有课程的平时成绩和才试成绩
select student.学号,student. 姓名,score.课号,score.平时成绩,score.考试成绩
from student,score
where student.姓名='张三'
and student.学号=score.学号
order by score.才试成绩 desc,score.平时成绩 desc
使用表别名简化语句
例:
select st.学号,st.姓名,c.课名,s.平时成现,s.考试成绩
from student as a
score as b
sourse as c
where st.姓名='张三'
and st.学号=s.学号
and s.课号=c.课号
例:查询“计算机基础”课程,考试成绩大于等于90分的学生的学号、姓名、系别和考试成绩,并按考试成绩降序排序
select st.学号,st.姓名,st.所属院系,s.考试成绩
from score as s ,
course as c,
student as st
where c.课名='计算机基础'
and s.考试成绩>=90
and s.课号=c.课号
and st.学号=s.学号
order by s.考试成绩 desc
使用 inner join 连接查询
语法:
select * (或字段列表)
from 表名1
inner join 表名2
on 连接规则
inner join 表名3
on 连接规则
其中,关键字“ON”之后是连接表的规则
高级查询
自连接查询
例:
select st1.*
from student as st1,student as st2
where st1.所属院系=st2.所属院系
and st2.姓名='张三'
或:
select *
from student as st1,student as st2
where st2.姓名='张三'
and st1.所属院系=st2.所属院系
外连接查询
左外连接:
例:
select *
from student left outer join student2 on student.姓名=student.姓名
右外连接:
例:
select *
from student right outer join student2 on student.姓名=student.姓名
全外连接:
例:
select *
from student full outer join student2 on student.姓名=student.姓名
左外连接
select * from student left outer join student2 on student.姓名=student2.姓名
右外连接
select * from student right outer join student2 on student.姓名=student2.姓名
全外连接
select * from student full outer join student2 on student.姓名=student2.姓名
组合查询(注意:因为组合查询结果集的字段名列表是根据第一个select子句的字段名列表而定的,所以用户在使用order by 时应当注意这一点)
组合查询使用union 关键字
语法:
select 语句1
union
select 语句2
union
select 语句3
例:从student表中,查谒来源地为“北京市”或“江苏省”或“内蒙古自治区”的学生的所属院系信息。
select 所属院系
from student
where 来源地='广东省'
union
select 所属院系
from student
where 来源地='江苏省'
union
select 所属院系
from student
where 来源地='内蒙古自治区'
使用union 得到复杂的统计江总样式
例:
select 学号,课号,考试成绩
from student
union
select 学号,'总分',sum(考试成绩)
from student
group by 学号
select 学号,'总分',avg(考试成绩)
from student
group by 学号
第12章
子查询
返回单值的子查询
返回一列值的子查询
相关子查询
嵌入另一个seelct语句中的select语句称为子查询。目前,子查询能完成的工作通过表连接几乎都可以完成,而在过去,因为内连接的运行效率 比较差,外连接又不能使用,所以子查询被运用重非常广。但是,由于开发人员在过去几年对DBMS的优化,使得内连接的运行效率明显优于子查询,面外连接也 被开发出来。所以人们开始放弃那些难理解的子查询语句,而改用相对容易理解的表连接查询语句。
虽然多数情况下,使用表连接查询要优于子查询,但是,在特定环境下,子查询运行的效率可能优于表连接查询。为了能够阅读、理解早年编写的SQL语句,所以本书还是将子查询的内容加入了进来。
使用返回单值的子查询
例:查询所有学生“心理学”的考试成绩,并以考试成绩降序进行排序
select 学号,考试成绩
from score
where 课号=(select 课号 from course where 课名 ='心理学')
order by 考试成绩 desc
子查询与聚合函数的配合使用
例:查询出生日期最小的学生的所有信息
select *
from student
where 出生日期=(select min(出生日期) from student)
例:查询“心理学”考试成绩大于其考试成绩大于其考试成绩平均分的所有学生的学号、平时成绩和考试成绩。
select 学号,平时成绩,考试成绩
from score
where 课号=(select 课号 from course where 课名='心理学') and 考试成绩>(select avg(考试成绩) from score where 课号=(select 课号 from course where 课名='心理学'))
使用in 的子查询
例:使用in的例子
select 课号
from score
where 课号 in (select 课号 from course where 类型='必修')
相关子查询(它是一种使用SQL的旧方法,查询的效率非常低,不提倡使用。只要明白就可以)
第13章 视图
视图基础
视图的创建
视图的删除
本章将讲解SQL中的另一个概念--视图。视图在数据库应用中经常会出现,它最主要的应用是简化复杂的查询语句。视图是由英文单词VIEW翻译过来的名词,其实VIEW还有“查看”的意思,笔者认为有时该单词译成“查看方式”可能更贴切一些。
视图基础
例:定义一个视图vw1,将一个查询语句放入视图内
create view vw1
as
select * from student
使用视图时:
select * from vw1
视图的删除:
drop view vw1
视图建立语法:
create view 视图名
as
数据库操作语句
例:
create view view_student_all
as
select st1.*,st2.*
from student as st1 join student2 as st2 on st1.姓名=st2.姓名
利用视图提高数据安全性
1.隐藏列数据
例:创建一个只能查看 学号 姓名 和 性别 3个列的视图 vw_student1
create voiw vw_student1
as
select 学号,姓名,性别
from student
2.隐藏行数据
例:创建一个只能查看计算机系学生信息析视图vw_student2
create view vw_student2
as
select *
from student
where 所属院系='计算机系'
利用视图得到汇总数据
例:创建一个视图vw_student3,显示每个不同院系的学生人数。
create view vw_student3
as
select 所属院系,count ( * ) as 人数
from student
group by 所属院系
第14章
插入数据
直接向表插入数据
通过视图插入数据
向数据表插入数据也是SQL语言最基本的功能之一。插入数据有多种方法,也需要遵循一定的规则。插入数据使用的SQL语句是INSERT。本章将详细介绍INSERT的各种用法和使用时需要注意的规则。
直接向表插入数据
insert into 表名或视图名
values (字段1的值,字段2的值。。。)
例:插入一条数据
insert into student(姓名,性别,总分,平时成绩,address,所属院系)
values ( '大彪','男',99,99,'中国长春','计算机软件工程')
将查询结果插入表
语法:
insert into 表名(字段表)
select 语句
例:将student表中查询到的数据存到student2中
insert into student2
select * from student where 姓名='大彪'
insert select 与 select into 的区别
insert select 将表中查询到的内容插入到另一个表中
select into 将表中查询到的内容重新保存为一个新表
通过视图插入数据
例:先建立视图
create view vw_computer
as
select *
from student
where 所属院系='计算机系'
在创建视图后执行下面语句
select *
from vw_computer
查询 所属院系 为 计算机系 的数据。
再进行插入操作
insert into vw_computer
values ( '0017','蒋十九','女','1982-05-09','山东省',null,null,'计算机系' )
with check option
最后的一句 with check option 是为了保证插入的数据内,所属院系=计算机系,这样才可能使数据安全,因为视图操作的只是 计算机系 的学员信息。