mysql的子查询,多表查询,连接查询(小白推荐)

前言

今天给小伙伴分享的是mysql的 子查询,多表查询,连接查询,由于小编状态不好,所以
如果写的有问题,请多多指教。

子查询(嵌套查询)

定义:把内层的查询结果作为外层的查询条件,子查询通常比外层查询优先级更高

语法:select … from 表名 where 条件(select …);

直接来看道题目吧:

数据准备:
    CREATE TABLE `sg` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `name` varchar(8) DEFAULT NULL,
      `attack` int(11) DEFAULT NULL,
      `defense` int(11) DEFAULT NULL,
      `gender` char(1) DEFAULT NULL,
      `country` varchar(8) DEFAULT NULL,
      PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8

INSERT INTO sg VALUES
    (1,"诸葛亮",99,90,"男","蜀国"),
    (2,"司马懿",98,97,"男","魏国"),
    (3,"貂蝉",69,100,"女","东汉"),
    (4,"张飞",105,20,"男","蜀国"),
    (5,"赵云",130,103,"男","蜀国");

    这个表大家应该都能看懂吧,三国表,id为主键,默认编码utf-8,引擎 InnoDB
  1. 把攻击值小于平均攻击值的英雄名字和攻击值显示出来
select name,attack from sg where attack < (select avg(attack) from sg);

/*
    应该不难理解吧,个人觉得主要还是主看条件
    条件1:attack < xx 
    而xx就是聚合函数,平均值,有小伙伴可能会说为啥不能 attack < avg(attack),小伙伴可以看我
    写的另一篇文章(普通查询),聚合函数它只能出现在 select 后面 from的前面或出现在HAVING子句中,用于对分组后的结果进行条件过滤,
    这是规定,所以这里子查询得到 avg(attack) 是必要的
*/
有小伙伴会说,这道题目不是很简单吗,子查询就这?这里我们可以看到它的要求非常少,就一个 attack < xx,做查询
题目,首先先注意条件,标注出多少条件,单查询能做到何种程度,然后再子查询或别的查询完成其它条件,接下来看
一道比较难的题目。表数据给大家了,小伙伴跟着一起做吧
  1. 找出每个国家攻击力最高的英雄的名字和攻击值(子查询)
分析:
     条件1:每个国家 ---》group by country
     条件2:攻击力最高 ---》max(attack) 
     条件3:查name和attack
    
    先把条件写下来,很明显 name和attack是最终要查的,name和attck肯定在外层
    聚合函数max(attack)就是作为条件的子查询,而分国家attack最高,明显分组(按国家分)也是在子查询中,大概写出。
    select name,attack from sg 
        where xx (select country,max(attack) from sg group by country)

    子查询会形成两列临时表  country attack 两列的表和数据,很明显我们需要这两列作为条件去匹配查询数据,从
    而得到结果。

where () in (): 外部查询,where () in () 匹配相符合的每一行

# 使用 where () in () 匹配我们子查询得到的数据结果,然后作为条件去匹配查询name和attack
select name attack from sg
    where (country,attack) in 
    (select country,max(attack) from sg group by country);

多表查询

  • 笛卡尔积
  假如有两个表 t1(id name,phone) t2(id,class,country)
  然后直接 select * from t1,t2;
  这个是可以实现的,但是数据是混乱的,会出现9条数据,就会数的组合的可能性一样,2条与2条
  数据组合,会有4种组合,3X3组成,会有9种,这种现象就是笛卡尔积,
  尽量避免这种查询,如果出现了,我们老师说你可以提包跑路了
  • 语法

select * from 表1,表2 where; # 使用where后进行了一遍筛选,但实际还是进行了大量无用的查询,所以别用

连接查询

内连接

结果实际上和多表查询(含where)的一样,但是它是两个表连起来后然后进行查询,所以效率比多表查询肯定更高

  • 语法

select 字段名 from 表1 inner join 表2 on 条件 inner join 表3 on 条件; #(看你查的多少个表)

  • 缺点

因为它是多表连接以后进行的筛选查询,两表的数据都有,有时会查出许多无用的数据

左外连接

  • 语法

select 字段名 from 表1 left join 表2 on 条件 left join 表3 on 条件

左外连接理解:
  以左表为主”,指左表中的记录不管右表是否有对应的匹配记录,都会被包含在最终的查询结果中。这种类型的连接通常用于确保查询结果能够列出左表中的所有记录,同时尽可能地从右表中获取匹配的数据。如果右表没有,那就会显示null

  由于表的数据太多太长,还有多个表,不好演示,大家可以用自己的表去 对比内连接和外连接的区别

右外连接

  • 语法

select 字段名 from 表1 right join 表2 on 条件 right join 表3 on 条件

原理同上,以右表为主

结语

我刻意削弱了语法层面的知识,而是更多的和大家说原理,用实际去说明它,我觉得学编程就是这样,不要去背,
以前学数据库的时候老是去记忆它,但是当你从实际问题入手,少了什么,知道有什么可以去做它,原理是怎么样的,
就算语法上忘记了,可以百度找答案,当解决的问题多了以后,慢慢就记住了。
愿大家可以把数据库学好,只要是学编程我觉得都离不开它,它非常重要。
  • 17
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值