在mysql中,只支持union(并集)集合运算,而对于交集intersect和差集except并不支持。那么如何才能在mysql中实现交集和差集呢?
一般在mysql中,我们可以通过in和not in来间接实现交集和差集,当然也有一定局限性,面对少量数据还可以,但数据量大了效率就会变得很低。
创建table1
/*ddl 信息*/------------
create table `t1` (
`id` int(11) not null,
`name` varchar(20) default null,
`age` int(11) default null,
primary key (`id`)
) engine=innodb default charset=utf8
创建table2
/*ddl 信息*/------------
create table `t2` (
`id` int(11) not null,
`name` varchar(20) default null,
`age` int(11) default null,
primary key (`id`)
) engine=innodb default charset=utf8
插入
insert into t1 values(1,'小王',10);
insert into t1 values(2,'小宋',20);
insert into t1 values(3,'小白',30);
insert into t1 values(4,'hello',40);
insert into t2 values(1,'小王',10);
insert into t2 values(2,'小宋',22);
insert into t2 values(3,'小肖',31);
insert into t2 values(4,'hello',40);
select t1.* from t1
id name age
1 小王 10
2 小宋 20
3 小白 30
4 hello 40
select t2.* from t2
id name age
1 小王 10
2 小宋 22
3 小肖 31
4 hello 40
使用not in 求差集,但效率低
select t1.* from t1
where
name not in
(select name from t2)
id name age
3 小白 30
select t1.id, t1.name, t1.age
from t1
left join t2
on t1.id = t2.id
where t1.name != t2.name
or t1.age != t2.age;
id name age
2 小宋 20
3 小白 30
求交集,此时只有id name age 所有都一样才是符合要求的。
select id, name, age, count(*)
from (select id, name, age
from t1
union all
select id, name, age
from t2
) a
group by id, name, age
having count(*) > 1
id name age count(*)
1 小王 10 2
4 hello 40 2
union all和union的区别
union和union all的功能都是将两个结果集合并为一个,但是这两个关键字不管从使用还是效率上来说,都是有一定区别的。
使用上:
1、对重复结果的处理:union在进行表链接后会筛选掉重复的记录,而union all则不会去除重复记录。
2、对排序的处理:union将会按照字段的顺序进行排序;union all只是将两个结果合并后就返回,并不会进行排序处理。
效率上:
从效率上说,union all的处理效率要比union高很多,所以,如果可以确认合并的两个结果集中,且不包含重复数据和不需要进行排序的话,推荐使用union all。
相关阅读:
原文地址:https://blog.csdn.net/mine_song/article/details/70184072