小蔺的米哈游数据分析师之路——MYSQL子查询及简单多表查询篇

        经过前几次的学习,目前我们已经可以熟练掌握MySQL中的增删改查操作了那么为了我们更好的使用MySQL来查找我们需要的数据,我们今天来进行更深入的学习。

   一,子查询

        子查询的含义非常简单,我们想用一个查询的结果作为另一个查询的条件,我们就可以利用子查询来实现需求

        我们来看一个实例:

        例如我们需要知道在player表中,有哪些玩家的等级大于平均等级,那我们目前的思路可以分为两步:
        1,查找目前玩家的平均等级
        2,查找等价大于平均等级的玩家

        这里相信大家第一步已经很熟练了,我们就不过多的演示,那么我们直接进入第二步,只需要输入:

select * from player where level > (select avg(level) from player );

         我们可以看出来,子查询其实就是我们将我们的查询结果作为我们的查询结果作为我们的查询条件进行查询,当然我们也可以查寻我们每个玩家的等级以及他们和平均等级间的差值,这时候只需要输入:

select 
    level,round((select avg(level) from player)),level - round((select avg(level) from player))
from  player;

        这样我们不但查询到了我们平均年龄,还看到了我们每位玩家和平均等级间的差距,由于玩家的等级都会是证书,所以我们这里使用了round来对我们查询到的内容进行了一个取整

        那么新的问题来了,我们在查询到的结果中看到我们字段上的名称显示的很长,对于我们的读者来讲,很难直接看出我们查询出来的是什么信息,那么我们就可以给他们进行一个命名,一般我们只需要在名称后面加上as (当然这里的as可以进行省略)即可:

select 
    level,round((select avg(level) from player)) as average ,
    level - round((select avg(level) from player))  as diff
from  player;

        运行语句,我们就可以看到我们的列名变为了average 和 diff 

        学习了命名之后我们继续来看我们的子查询,子查询不但可以嵌套查询,我们也可以用子查询来新建表,例如我们想查找等级小于5的玩家并新建成为一张名为new_player的表,那我们可以输入:

create table new_player 
    select * from player 
    where level < 5;

        运行后我们刷新一下我们的数据库就可以看到新表生成了,大家感兴趣的话也可以查看一下表中的数据看看我们的表是否成功创建了

        我们不仅可以创建新表,同时子查询还可以通过查询新建数据,大家可以回忆一下我们原来插入数据的代码是什么,那么这里我们输入

insert into new_player 
    select * from player
    where level between 6 and 10;

        即可插入数据了。

        子查询同样也可以支持我们对于查询的结果进行判断,比如我们需要查找是否有等级大于100级的玩家,那么我们在这里需要引用一个概念exists

exists用来判断是否有结果,符合则输出1,否则输出0

         那我们输入代码:

select exists (select * from player where level > 100);

         可以看到这里返回了0,代表目前并不存在等级大于100级的玩家,想同,如果我们将100改为10呢,再次运行我们可以看到,输出值变为了1,代表了我们目前输出结果中有等级大于10级的玩家

二,表关联

        表关联可以用来查询多个表中的数据,我们可以用表关联来将多个表进行联合查询,同样关联的表中需要有相同的字段才可进行关联操作,一般的关联会使用主键(primary key)和外键(foreign key)来进行关联,一般关联分为三类:

内连接(inner join):返回两表中均有的数据

左连接(left join):返回左表中的数据,以及和右表匹配的数据,右表没有的用null填充

右连接(right join):返回右表中的数据,以及和左表匹配的数据,左表没有的用null填充

         那么我们在这里演示表关联的时候引入了一张新的表,装备表,我们可以看下表中的字段:

        字段非常简单,那么我们现在需要把 玩家表和装备表关联,就可以用inner join 来操作,输入

select * from player
    inner join equip 
    on player.id = equip.player_id;

        运行后我们可以看到我们表中现在不但有了玩家的信息,还有了他们装备的信息,那如果我们换成左连接呢,我们再次输入下
        

        我们可以看到结果中包含了所有玩家的信息 以及装备表的所有信息,没有的将会用null来进行填充,那么同样,大家也可以使用right来试一下我们会输出什么样的结果

        在我们实际使用中,我们的内连接是可以隐藏的,这样写出来的内连接语句我们可以称之为,隐式内连接,同时我们在这个时候也觉得给表每次输入全名有些麻烦,那么我们对于这些表也可以进行一个命名,例如还是刚刚的内连接,我们换成

SELECT * FROM player p , equip e  
	WHERE  p.id = e.player_id;

        

        我们可以看到我们的查询也是查询到了一样的结果

        在这里我们需要注意的是,在我们显示内连接中 使用的语句是inner join ......on......

隐式内连接中用的是 .......where........

        当然我们在查询的过程中如果进行了错误的查询,就会查询到笛卡尔积的结果 

笛卡尔积百度上的解释为:令A和B是任意两个集合,若序偶的第一个成员是A的元素,第二个成员是B的元素,所有这样的序偶集合,称为集合A和B的笛卡尔乘积或直积,记做A X B

        我们可以演示一下,例如我们去掉where查询掉件,查询后:         我们可以看到张三和每一件装备都匹配到了值,并且生成了数据

        这里我们查询到了总共数据有1881条,那我们分别查询player和equip表中的数据,分别为209条和9条,刚好等于两表数据量之积,那么相信大家也理解了笛卡尔积是什么了,其实表连接的本质就是我们的笛卡尔积加上条件过滤,当我们没有过滤条件时,表就会生成笛卡尔积,遇到这种情况时,我们需要特别注意下。

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值