前言
今天给小伙伴分享的是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
- 把攻击值小于平均攻击值的英雄名字和攻击值显示出来
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:每个国家 ---》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 条件
原理同上,以右表为主
结语
我刻意削弱了语法层面的知识,而是更多的和大家说原理,用实际去说明它,我觉得学编程就是这样,不要去背,
以前学数据库的时候老是去记忆它,但是当你从实际问题入手,少了什么,知道有什么可以去做它,原理是怎么样的,
就算语法上忘记了,可以百度找答案,当解决的问题多了以后,慢慢就记住了。
愿大家可以把数据库学好,只要是学编程我觉得都离不开它,它非常重要。