MySQL實現差集(Minus)和交集(Intersect)
阿新 • • 發佈:2019-01-22
MySql只支援Union(並集)集合運算,好像也是4.0以後才有的;但是對於交集Intersect、差集Except,就沒有實現了。
一般的解決方案用in和not in來解決,小量資料還可以,但資料量大了效率就很低了
建立table1
建立table2/*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
/*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
求交集,此時只有id name age 所有都一樣才是符合要求的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
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。