目录
联合查询
连接查询
交叉连接
内连接
外连接
自然连接
子查询
标量子查询
列子查询
行子查询
表子查询
exist子查询
基本概念:联合查询是可合并多个相似的选择查询的结果.等同于将一个表追加到另一个表,从而实现将两个表的查询组合到一起,使用谓词为union或union all
联合查询:将多个查询的结果合并到一起(纵向合并):字段数不变,多个查询的记录数合并.
基本语法:
select 语句1
union [union选项] // union选项:1.distinct去重,(为默认选项); 2.all:保留所有数据.
select 语句2;
在联合查询中,如果要使用order by,那么对应的select语句必须使用括号括起来.
实例:男生身高升序排序,女生年龄降序排序
可以发现男生身高并没有升序排列,
还有一个细节要符合:order by在联合查询中若要生效,必须配合使用limit: 而limit后面必须跟对应的限制数量(通常可以使用1个较大的值:大于对应表的记录数)
如上,我们加了limit 10,order by语句生效了,排序正常.
连接查询:将多张表liandao连到一起进行查询(会导致记录数行和字段数列发生改变)
连接查询的意义:
在关系型数据库设计过程中,实体(表)和实体之间是存在很多联系的.在关系型数据库表的设计过程中,遵循着关系来设计:1对1,1对多,多对多.通常在实际操作的过程中,需要利用这层关系来保证数据的完整性.
将两张表的数据与另外一张表彼此交叉
记录数=第一张表记录数x第二张表记录数;字段数=第一张表字段数+第二张表字段数(笛卡尔积)
//前面说过,笛卡尔积没有意义,应该避免使用
内连接: inner join,
从一张表中取出所有记录去另外一张表中匹配:利用匹配条件进行匹配.成功则保留;失败则放弃.
原理
1. 从第一张表中取出1条记录,然后去另外一张表中去匹配
2. 利用匹配条件匹配:
2.1 匹配到:保留,继续向下匹配
2.2 匹配失败:向下继续.如果全表匹配失败,结束.
语法:
表1 [inner] join 表2 on 匹配条件;
1. 如果内连接没有匹配条件,那么其实就是交叉连接(应避免).
2.使用匹配条件进行匹配
如下所示有两个表 student, teacher,
匹配条件为:学生表中学生所属的id = 教师表中的teacher_id 。满足则保留该记录.不满足则舍弃.
3. 因为表设计通常容易产生同名字段,尤其是id,所以为了避免重名出现错误,
通常使用 表名.字段名 来确保唯一性.
两个表都有个张三,且同为name属性,只能使用这个方式实现
内连接通常是在对数据有精确要求的地方使用:必须保证两张表中都能进行数据匹配
outer join:按照某一张表作为主表(表中所有记录在最后都会保留),根据条件去连接另外一张表,从而得到目标数据.
外连接分两种:左外连接left join;右外连接right join
左连接:左表是主表.
右连接:右表是主表.
原理
1. 确定连接主表是左表还是右表;
2. 拿主表的每一条记录,去匹配另外一张表(从表)的每一条记录;
3. 如果满足匹配条件,保留;不满足则舍弃;
4. 如果主表记录在从表中一条都没有匹配成功,那么也要保留该记录:从表对应的字段值为null
语法:
左连接:主表 left join 从表 on 连接条件;右连接:从表 right join主表 on 连接条件;
左连接对应的主表数据在左边; 右连接对应的主表数据在右边.
以上是左连接(主表是左边),下面是右连接(主表是右边)
一般就用左连接
定义:自然连接是一种系统自动设定匹配条件的连接方式,匹配的原理是两张表的同名字段.
1.自然连接不是一种特定的连接方式,而是一种自动匹配条件的连接方式,自然连接支持内连接和外连接
自然内连接:natural join
自然外连接:natural left/right join
注意:自然连接会将同名字段只保留1个.(即只保留一个同名字段)
子查询是一种计算机语言 select-sql语言中嵌套查询下层的程序模块.当一个查询是另一个查询的条件时,称之为子查询.
子查询:在一条select语句中,嵌入了另外一条select语句,那么被嵌入的select语句成为子查询语句.
主查询概念
主查询:主要的查询对象,第一条select语句,确定的用户所有获取的数据目标(数据源),已经要具体得到的字段信息
子查询和主查询关系
1.子查询是嵌入到主查询中的
2. 主查询辅助主查询:要么作为条件,要么作为数据源
3. 子查询其实可以独立存在:是一条完整的select语句
子查询分类
按功能分
按位置划分
标量子查询:子查询得到的结果是1个数据(1行1列)
语法:
select * from 数据源 where 条件判断 =(select 字段名 from 数据源 where 条件判断);//子查询得到的结果只有1个值
如下演示 知道一个学生名字是李四 ,与他id相同的老师是谁?
(需求决定主查询 teacher)(条件决定子查询 student)
概念:列子查询:列子查询得到的结果是一列数据(一列多行)
语法:
主查询 where 条件 in (列子查询);
想要得到 id能与teacher_id 对应的所有学生的名字学
行子查询:行子查询返回的结果是一行多列
行元素:
字段元素是指一个字段对应的值,那么行元素对应的就是多个字段:、
多个字段合起来作为一个元素参与运算,把这种情况称之为行元素.
语法:
主查询 where 条件 [(构造一个行元素)]=(行子查询);
在student中找到一个 年龄 身高 都最大的学生信息
总结:
已经学过3个子查询.标量子查询,列子查询,行子查询都属于where子查询.
表子查询:子查询返回结果是多行多列,表子查询与行子查询非常相似.只是行子查询需要产生行元素,而表子查询没有.
行子查询是用于where条件判断:where子查询
表子查询是用于from数据源:from子查询
语法
select 字段表 from (表子查询)as 别名 [where] [group by] [having] [order by] [limit];
这是 student 表的数据
我们想查询每个班身高最高的学生
select * from student group by class having height = max(height);
这样行不通,因为group by 分组后只会保留每组第一条数据,那么我们可以排序
select * from (select * from student order by height desc) as temp group by class;
注意:一定要有 as 别名
概念:exist子查询查询的结果只有0或1.1代表成立,0代表不成立.
语法:
where exist (查询语句);
//exist就是根据查询得到的结果进行判断:如果存在返回1,否则返回0
注意mysql中where 1:永远为真
举例
想要得到 id能与teacher_id 对应的所有学生的名字
exists判断为true 则保留,false 则不保留