版权声明:本文为博主原创文章,未经博主允许不得转载。 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