【章节7】汇总和分组、连接(join)、子查询(in和exists)和联合查询(union)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/a786150017/article/details/78905782

汇总和分组数据

1.聚合函数 

执行某个查询语句→会生成结果集(多条数据)→经过聚合函数后会生成单行记录
e.g 求平均分、总分

常用的聚合函数


示例1(查询玩家表中一共有多少名玩家信息):       

select count(USER_QQ) from USERS    #只统计了非空行数
select count(*) from USERS    #只要行上任意列不为空,就进行统计
示例2(查询QQ号是12301的玩家游戏的总分数):      
select sum(SCORE)  as ‘总分数’ from SCORES where USER_QQ = 12301
示例3(查询QQ号是12301的玩家游戏的平均分):       
select avg(SCORE)  as ‘平均分数’ from SCORES where USER_QQ = 12301
示例4(查询游戏编号是1的游戏的最高分):      
select max(SCORE)  as ‘最高分’ from SCORES where GNO = 1
示例5(查询QQ号是12302的玩家的总分、平均分和最高分):
select 
sum(SCORE)  as ‘总分数’,
avg(SCORE)  as ‘平均分数’,
max(SCORE)  as ‘最高分’ 
from SCORES where USER_QQ = 12302

2.在结果集中分组 group by

查询语句生成多条语句的结果集→聚合函数+group by→生成多条记录

示例1:查询每个玩家的总分数、平均分、最高分

select
USER_QQ, 
sum(SCORE)  as ‘总分数’,
avg(SCORE)  as ‘平均分数’,
max(SCORE)  as ‘最高分’ 
from SCORES group by USER_QQ

分组结果如下:


示例2:查询每个玩家的平均分数,并显示玩家QQ号和平均分数

select USER_QQ,
avg(SCORE) as '平均分'
from SCORES group by USER_QQ

分组结果如下:


3.筛选分组结果    having一定在group by后;order by

例如,先统计总分→筛选分数


示例1:查询平均分数大于3000分的玩家QQ号、总分数、平均分数

select USER_QQ,
sum(SCORE) as '总分数',
avg(SCORE) as '平均分'
from SCORES 
group by USER_QQ
having avg(SCORE) > 3000
示例2:查询所有用户的平均分数和总分数,并按平均分数倒序排列
select USER_QQ,
sum(SCORE) as '总分数',
avg(SCORE) as '平均分'
from SCORES 
group by USER_QQ
order by avg(SCORE),desc

4.select语句的执行顺序

聚合函数sum、avg等  as  别名
from —— 数据源
where —— 第一层过滤
group by —— 划分为多个分组
having —— 筛选分组
order by —— 排序

连接查询

1.from子句进行多表查询     from 表1,表2,表3

希望查询结果显示下图:


假设有T1,T2两张表
select * from T1,T2        #笛卡尔积    需要排除掉不合要求的


示例1:查询分数信息,显示玩家昵称、游戏名称和分数

select USER_NAME '昵称',GNAME '游戏名称',SCORE '分数'
from USERS,GAMES,SCORES
where USERS.USER_QQ = SCORES.USER_QQ and GAMES.GNO = SCORES.GNO
#where表示约束条件

2.内连接  两张表地位平等

隐式内连接
select 列1,列2 from 表1,表2 where 表1.列 = 表2.列
显式内连接:    更快
select 列1,列2 from 表1 [inner] join 表2 on 表1.列 = 表2.列


示例1:查询分数信息,显示玩家昵称、游戏名称和分数

select USER_NAME '昵称',GNAME '游戏名称',SCORE '分数'
from GAMES inner join SCORES
on GAMES.GNO = SCORES.GNO
inner join USERS
on USERS.USER_QQ = SCORES.USER_QQ
示例2:查询每个玩家的昵称、总分和平均分
select USER_NAME '昵称',sum(SCORE) '总分',avg(SCORE) '平均分'
from USERS U inner join SCORES S    #起别名
on U.USER_QQ = S.USER_QQ
group by U.USER_QQ,USER_NAME    #按USER_QQ进行分组,按USER_NAME进行显示
示例3:查询平均分大于3500的分数信息,显示玩家昵称、总分数和平均分数,并按照平均分数降序排序
select USER_NAME as ‘昵称’,sum(SCORE) as '总分数',avg(SCORE) as '平均分数'
from USERS U inner join SCORES S
on U.USER_QQ = S.USER_QQ
group by USER_QQ,USER_NAME
having avg(SCORE) > 3500
order by avg(SCORE) desc

3.外连接  

两张表地位不平等,其中有一张是基础表(数据一定会出现)


格式:

select 列1,列2
from 表1 left|right [outer] join 表2
on 表1.列 = 表2.列

示例1:查询所有玩家关于5号游戏的分数信息

select USER_NAME as ‘昵称’,GNO as '游戏编号',SCORE as '分数'
from USERS U left join SCORES S
on U.USER_QQ = S.USER_QQ
and S.GNO = 5

子查询

1.使用in关键字进行子查询

示例1:查询游戏类型是"棋牌类"的游戏的分数信息
select * from SCORES where GNO in
(select GNO from GAMES where GTYPE ='棋牌' )   #查询棋牌类游戏的编号
子查询和父查询

示例2:查询没有参与5号游戏玩家的QQ号

注意:分数表中没有包含所有的玩家QQ

select USER_QQ from USERS
where USER_QQ not in
(select USER_QQ from SCORES where GNO = 5)

2.使用exists关键字进行子查询

exists后面跟的查询有结果,会执行外围的父查询
示例3:如果存在昵称为‘孙悟空’,则查询分数表中的数据
select * from SCORES
where exits (select * from USERS where USER_NAME ='孙悟空')

*exists后面的子查询至少存在一个数据(有结果),则进行外围父查询

联合查询

1.联合查询

select语句 union [all] select语句 ...
    将两个查询语句查询到的结果集-纵向连接到一起
    [all关键字]:显示全部数据(重复的也显示)
    两个语句结果集-列的数量要相同

示例1:查询玩家表中所有女性玩家和生日为空的玩家

select * from USERS where USER_SEX = '女'
union
select * from USERS where USER_BIRTHDAY is NULL
法2:
select * from USERS where USER_SEX = '女' or USER_BIRTHDAY is NULL
示例2:查询QQ号是2016的玩家所有分数,计算总分数和平均分数,并显示到同一结果集中:
select USER_QQ,GNO,SCORE from SCORES where USER_QQ = 2016
union all
select  '总分','  ',sum(SCORE) from SCORES where USER_QQ = 2016        # '总分',' ',sum(SCORE)是为了凑成三列
union all
select '平均分' ,'  ',avg(SCORE) from SCORES where USER_QQ = 2016

结果如下:


法2:

select SCORE,avg(SCORE),sum(SCORE) from SCORES where USER_QQ = 2016




猜你喜欢

转载自blog.csdn.net/a786150017/article/details/78905782