勿以恶小而为之,勿以善小而不为--------------------------刘备

上一章简单介绍了 MySQL的子查询(二十),如果没有看过,​​请观看上一章​​

一. 合并查询结果

多条sql 查询语句的合并处理,有两种不同的形式,
第一种是子查询, 一些sql查询语句的输出是另一条sql查询语句的输入,

第二种是 合并查询结果, 将多条查询结果结构相同的数据进行合并运算。
第一次查询出来的是一个二维表,第二次查询出来的也是一个二维表, 那么就可以将这两次的查询结果进行合并,
合并包括取并集, 取交集, 取差集。

但是 MySQL数据库只支持 并集(union 和union all),不支持交集(intersect) 和差集(minus)。

要想对前后不同的查询语句的结果进行合并,必须要保证 前后的查询结果的结构是一样的。(查询的列名总数一致,与列名结构的排列顺序无关,与查询出来的结果行数量无关)

查询语句1:

语句1: select * from user ;

语句 2: select id,name from user;

猜想1:

语句1 会将user 表中的所有的列都查询出来,包括id,name,sex,birthday,age,description ,

语句2 只会查询出 id,name 的两行列

列的总数是不一致的,结构不同,所以这两次的查询结果是不能合并的。

查询语句2:

语句 3: select * from user;

语句 4: select * from user where id=1;

猜想2:

语句 3会查询出所有的列, 多条记录

语句4 会查询出所有的列, 一条记录

列的总数一致,排列顺序也一致,所以结构是相同的,可以进行合并。

查询语句3:

语句 5: select id,name,age from user;

语句 6: select id,name,age from user where id=1;

猜想3:

语句 5只会查询出 id 和name,age 三个列, 多条记录

语句 6 会查询出id,name 三个列,但只有一条记录

列的总数一致,都是三列,顺序也一致,结构相同,所以是可以合并的。

查询语句4:

语句 7: select id,name,age from user;

语句 8: select name,id,age from user where id=1;

猜想4:

语句 7 只会查询出 id,name,age 三个列,多条记录,类型依次是 int,varchar,int

语句 8 只会查询出 name,id,age 三个列,单条记录, 类型依次是 varchar,int,int

列的总数一致,都是三列,虽然前后的类型不一致,但依然是可以合并的。

二. 并集 union 和 union all (重要)

union 和 union all 是求并集的, 将前后的查询结果进行合并。
其中,union 是先去重,后合并,不保留重复的数据, union all 是直接合并,会保留重复的数据。 两者是有一些区别的。

如 查询 id>=3 和 id<=4 的数据。

查询 id>=3的结果:

select * from user where id>=3;

MySQL合并查询结果(二十一)_union all 的用法

查询 id<=4的结果:

select * from user where id<=4;

MySQL合并查询结果(二十一)_union all 的用法_02

两次查询结果中, 有相同的数据, 那就是 id=3和 id=4的数据。

二.一 union 先去重,后合并

select * from user where id>=3
union
select * from user where id<=4;

MySQL合并查询结果(二十一)_MySQL的结果差集_03

查询顺序 是先展示 id>=3 的数据,再展示 id<=4 的顺序, 如果 有重复的,则先去重。

union 最后查询出来的结果,没有重复的数据。

二.二 union all 直接合并

select * from user where id>=3
union all
select * from user where id<=4;

MySQL合并查询结果(二十一)_MySQL的合并查询结果_04

union all 并不会去掉重复的数据, 而是直接拼接后展示。

问题1: 如果前后查询列不一致,会报什么错误呢?

select id,name,age from user where id>=3
union
select * from user where id<=4;

MySQL合并查询结果(二十一)_MySQL的union的用法_05

ERROR 1222 (21000): The used SELECT statements have a different number of columns

问题2: 前后类型不一致,能合并吗?

select id,name,age from user where id>=3
union
select name,id,age from user where id<=4;

MySQL合并查询结果(二十一)_union all 的用法_06


可以进行合并,只是 合并后的数据有些问题。

三 交集

查询交集,可以利用子查询和连接查询进行处理。 from 语句的子查询和 内连接

如 还是查询 id>=3 和 id<=4 的数据, 它们的交集是 id=3 和id =4

交集,一定是 a 里面有的。

select t1.* from (
select * from user where id>=3
) t1
inner join (select * from user where id<=4) t2
on t1.id=t2.id and t1.name=t2.name ;

MySQL合并查询结果(二十一)_union all 的用法_07

其中 on 条件,是唯一标识, 这里用 id 和 name 两个标识, 实际开发中,只用一个 id 即可。

四 差集

查询差集, 也可以利用子查询和连接查询进行处理。 from 语句的子查询 和左外连接

查询 id>=3 和 id<=4 的数据,

如果是 id>=3 减去 id<=4 的, 那么查询出来的数据 就应该是 id>=5 的数据了。

查询出来的数据,一定在 id>=3 里面。

select t1.* from (
select * from user where id>=3
) t1
left join (select * from user where id<=4) t2
on t1.id=t2.id and t1.name=t2.name
where t2.id is null;

MySQL合并查询结果(二十一)_union all 的用法_08

如果 是 id<=4 减去 id>=3 , 那么查询出来的数据就应该是 id<=2 的数据了。

查询出来的数据,一定在 id<=4 里面。 这个时候,就应该用右连接了。

select t2.* from (
select * from user where id>=3
) t1
right join (select * from user where id<=4) t2
on t1.id=t2.id and t1.name=t2.name
where t1.id is null;

MySQL合并查询结果(二十一)_union all 的用法_09

谢谢!!!