勿以恶小而为之,勿以善小而不为--------------------------刘备
上一章简单介绍了 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;
查询 id<=4的结果:
select * from user where id<=4;
两次查询结果中, 有相同的数据, 那就是 id=3和 id=4的数据。
二.一 union 先去重,后合并
select * from user where id>=3
union
select * from user where id<=4;
查询顺序 是先展示 id>=3 的数据,再展示 id<=4 的顺序, 如果 有重复的,则先去重。
union 最后查询出来的结果,没有重复的数据。
二.二 union all 直接合并
select * from user where id>=3
union all
select * from user where id<=4;
union all 并不会去掉重复的数据, 而是直接拼接后展示。
问题1: 如果前后查询列不一致,会报什么错误呢?
select id,name,age from user where id>=3
union
select * from user where id<=4;
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;
可以进行合并,只是 合并后的数据有些问题。
三 交集
查询交集,可以利用子查询和连接查询进行处理。 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 ;
其中 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;
如果 是 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;
谢谢!!!