联合查询
所谓的联合查询就是将满足条件的结果进行拼接在同一张表中。
基本语法:
1 select */字段 from 数据表1 2 union [all | distinct] 3 select */字段 from 数据表2; 4 特别说明:使用union联合查询必须有一个前提,每个表读取的字段数必须是一致的
union联合查询默认是去重的。
union all :在数据联合时保存所有数据,示例代码:
union distinct :在数据联合时去重所有重复的数据,示例代码:
union的意义:主要用于大数据的存储,数据分表(针对大数据)。
例:数据库维护发现某个数据表(如产品表共有1亿条记录),运行非常缓慢。这个时候我们可以采用数据分表操作。把数据平均分成N份,每个数据表存储1/N数据量。
多表连接(两张以上的数据表)
1、多数据源
所谓的数据源就是一张提供数据的二维表,基本语法:
1 select * from 数据源,数据源,数据源...;
但是实际应用中,from后面的数据源可以同时有多个,两个数据源情况:
①返回的字段数= 数据源1+数据源2;
②返回的记录数 = 数据源1*数据源2; (笛卡儿积)
2、交叉连接
基本语法:
1 select * from 数据表1 cross join 数据表2;
交叉连接与多数据源(无where条件时),效果是一摸一样的。
①返回的字段数= 数据源1+数据源2;
②返回的记录数 = 数据源1*数据源2; (笛卡儿积)
特别说明:虽然在MySQL中存在交叉连接与多数据源连接(无where条件时),
但是返回的结果是笛卡儿积,而且这种数据是无意义的。在实际开发中,要避免出现以上情况。
3、内连接查询
基础语法:
1 select * from 数据表1 inner join 数据表2 on 关联条件; 2 或 3 select 数据表1.字段,数据表2.字段 from 数据表1 inner join 数据表2 on 关联条件;
①字段数= 数据表1 + 数据表2
②返回结果= 只获取两个表中满足关联条件的结果,不满条件的结果全部忽略
4、数据表与字段别名
基本语法:
1 数据表别名: 2 select * from 数据表 [as] 表别名; 3 字段别名: 4 select 字段 [as] 别名 from 数据表;
①数据表别名:简化SQL语句
②字段别名:避免产生字段冲突
字段冲突产生的后果就是后一个字段会覆盖前一个字段(PHP读取MySQL数据库),遇到以上情况必须对字段定义别名
5、多数据源查询(功能与inner join...on...类似)
基本语法:
1 select * from 数据源1,数据源2 where 条件;
6、左右外连接查询
①明确两个基本概念:左表与右表的概念
在连接查询中,处于左侧的表我们称之为“左表”;处于右侧的表我们称之为“右表”。
②基本语法:
1 左外连接查询: 2 select 左表.字段,右表.字段 from 左表 left join 右表 on 关联条件; 3 右外连接查询: 4 select 左表.字段,右表.字段 from 左表 right join 右表 on 关联条件;
特别说明:
1 内连接查询是只读取两个表中满足条件的结果,不满足条件的结果会自动忽略。 2 3 左外连接查询:以左表作为主表,读取其所有记录,然后去右表中进行数据匹配,满足条件,则获取匹配的记录,不满足条件则显示NULL。 4 5 右外连接查询:以右表作为主表,读取其所有记录,然后去左表中进行数据匹配,满足条件,则获取匹配的记录,不满足条件则显示NULL。
7、自连接查询
自连接查询:就是自己连接自己。
多级分类是如何实现的,通常我们会在数据表中添加一个额外的字段,叫parent_id(父类id)
子查询
什么是子查询?
1 子查询,指的是一个查询语句被其他语句包裹。 2 例: 3 select * from 数据表 where class_id = (select id from 数据表 where 条件);
子查询的分类?
1 ①按结构划分 2 from子查询 3 where子查询 4 exists 子查询 5 ②按返回结果划分 6 标量子查询,子查询的SQL语句返回固定的某个结果 7 列子查询,子查询的SQL语句返回某个字段列(一列信息,可能拥有多个结果) 8 行子查询,子查询的SQL语句返回一行记录信息(只有一条记录) 9 表子查询,子查询的SQL语句返回的一个表数据
子查询演示
①标量子查询,子查询返回的结果是固定的,例:求qz01中的所有学员信息
解析:子查询都是分段解析与执行的
1 第一步:求出全栈01期中的id信息 2 select id from tt_class where class_name=’qz01’; 3 4 第二步:在第一步的基础上,查询所有全栈01期的小伙伴信息 5 select * from tt_student where class_id = (?);
②列子查询,子查询返回的结果是一个字段列,例:求所有已经入班的学员信息
1 第一步:首先求出所有班级的id, 2 select id from tt_class; 3 4 第二步:在第一步的基础上读取所有已经入班的学员信息, 5 一般情况下列子查询通常结合in、not...in...、all、any以及some语句。 6 select * from tt_student where class_id in (?);
③ all、any以及some语句
all :必须满足all中的所有条件,其结果才会正常返回。id > all(1,3,5):要求id字段必须大于1且大于3且大于5。
any与some同义词:只要满足any中的某个条件,其结果就会立即返回。id> any(1,3,5) :只要id大于1,3,5中的某个值,其就可以正常返回。
1 select * from tt_student where class_id = all(select id from tt_class) 2 3 select * from tt_student where class_id = any(select id from tt_class)
④<>或!=与all、any以及some
!= + all 是not...in...的同义词:
############
!=与any :要求class_id不能等于any中的某个值。
########
⑤行子查询,子查询返回的结果是一个行信息(字段信息)
求:学员中年龄最大且身高最高的学员信息
1 第一步:获取班级中年龄与身高的最大值 2 select max(age),max(height) from tt_student; 3 4 第二步:获取学员的信息 5 select * from tt_student where (age,height) = (?);
⑥表子查询,返回的结果是一张数据表(多行多列)
求:每个班级中年龄最大的小伙伴信息
1 第一步:获取所有班级信息 2 select id from tt_class; 3 4 第二步:获取班级中的小伙伴信息 5 select * from tt_student where class_id in (?) 6 7 第三步:对第二步中的数据进行排序,按age降序 8 select * from (?)
⑦exists子查询
exists:判断内容是否存在,exists返回的结果就是true或false。
如果子查询返回1条以上的记录,mysql就认为其返回为true,反之,如果返回结果为空,则mysql就认为其返回false。
基本语法:
1 select * from 数据表where exists(子查询);
exists执行原理:咱们用过的子查询大多数都是把内层的子查询返回结果拿到外层的子查询中去运算。
但是exists比较特殊,其是把外层查询中的所有记录,
通过loop遍历循环的方式一条一条拿出来与exists中的返回结果进行比对,如果exists返回true,
则显示此记录,反之,则不显示此记录。