合查询:将多次查询(多条select语句),在记录上进行拼接(字段不会增加)。多条select 语句构成,每一条select语句获取的字段数必须严格一致(但是字段数据类型无关)。
1、联合查询基本用法。
基本语法:select 语句1 union [union 选项] select 语句2......
union 选项:
all:保留所有(不管重复)
distinct:去重(整个重复),默认的。
例子1、将my_foreign2表与class2表联合起来(字段个数相同,联合查询成功)。
先查询一下class2表和my_foreign2表中的数据。
联合查询。
例子2、将my_foreign2表与student3表联合起来(字段个数不同同,联合查询失败)。
联合查询:class2表与student3表。select * from class2 union select * from student3;
解决方案:由于class2表中只有3个列,因此在查询student3的时候查询3列(查询的列个数和class2表中的列个数相同)。
select * from class2 union select id,name,age from student3;
2、联合查询的意义。
联合查询的意义分为两种:查询同一张表和查询多张表。
a)、查询同一张表。
需求不同,如查询学生信息,男生的身高排序,女生身高降序。
b)、查询多张表。
多张表的结构是完全一样的,保存的数据(结构)也是一样的。
3、Order by 使用。
在联合查询中,order by 不能直接使用,需要对查询语句使用括号才行(每条查询语句都要使用括号),而且还要搭配 limit 才能生效。
例子:如查询学生信息,男生的身高排序,女生身高降序。
select * from student2 where sex = '男' order by age asc union select * from student2 where sex = '女' order by age ; -- 报错,使用order by 时,查询语句要使用括号括起来。
select * from student2 where sex = '男' order by age asc) union (select * from student2 where sex = '女' order by age desc) ; -- 能查询出信息,但降序不生效。要配合limit使用。
(select * from student2 where sex = '男' order by age asc) union (select * from student2 where sex = '女' order by age desc limit 99999) ; -- 正确查询。
4、子查询。
子查询:sub query,查询是在某个 查询结果之上进行的(一条select 语句包含了另外一条select 语句)。子查询分类方式有两种,按位置分类和按结果分类。
按位置分类:子查询(select语句)在外部查询(select语句)中出现的位置。
a)、From 子查询。
子查询跟在from 之后。
b)、where 子查询。
子查询出现where条件中。
c)、Exists子查询。
子查询出现在exists里面。
按结果分类:根据子查询得到的数据进行分类(理论上讲任何一个查询得到的结果都可以理解为二维表)。
a)、标量子查询(出现的位置在where之后)。
子查询得到的结果都是一行一列。
例子:查询【Class2】表中name = mysql(2)班的学生。
确定数据源:name = mysql(2)班的学生。
select * from student2 where c_id = (select id from class2 where name = 'mysql(2)班'); -- (select id from class2 where name = 'mysql(2)班'):返回的是首行首列(标量子查询)。
b)、列子查询(出现的位置在where之后)。
子查询得到的结果都是一行多列,一般配合着in、any 、all关键字使用。
例子:查询所有班级的在读的学生。
确定数据源:学生。
select * from student2 where c_id in(select id from class2); -- (select id from class2),返回的是多行多列(列子查询),因此要使用in来进行匹配。
c)、行子查询(出现的位置在where之后)。
得到的结果是多行一列或多行多列。
例子:查询整个学生中年龄最大,且身高最高的学生。
select * from student3 where age = (select max(age) from student3) and height = (select max(height) from student3); -- sql语句可写成这样。
如果按照上面的写法,总觉得代码量太大了,下面用行子查询的写法写。
select * from student3 where (age,height) = (select max(age),max(height) from student3);
(age,height) :称之为行元素。
(select max(age),max(height) from student3):查出的结果要与行元素的数量相对应。
d)、表子查询(出现的位置是在from之后)。
子查询得到的结果是多行多列,子查询返回的结果是当作二维表来使用(得到的结果作为from的数据源)。
例子:查询每个班级里最高的学生。
1、确定数据源,先将学生按照身高进行降序。select * from student3 order by height desc;
2、从每一个班里选第一个学生(通过c_id进行分组)。
select * from (select * from student3 order by height desc) as st group by st.c_id;
e)、Exists子查询。
exists:是存在的意思,exists子查询就是用来判断某些条件是否满足(多用于跨表),exists是接在where之后,exist返回的结果是0和1。
例子:根据exists返回的结果进行查询。
End。