MySQL交集和差集的實(shí)現(xiàn)方法

2022-08-04 17:37 更新

在MySQL中,只支持Union(并集)集合運(yùn)算,而對(duì)于交集Intersect和差集Except并不支持。那么如何才能在MySQL中實(shí)現(xiàn)交集和差集呢?


一般在MySQL中,我們可以通過in和not in來間接實(shí)現(xiàn)交集和差集,當(dāng)然也有一定局限性,面對(duì)少量數(shù)據(jù)還可以,但數(shù)據(jù)量大了效率就會(huì)變得很低。

創(chuàng)建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  

創(chuàng)建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  

求交集,此時(shí)只有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的區(qū)別

UNION和UNION ALL的功能都是將兩個(gè)結(jié)果集合并為一個(gè),但是這兩個(gè)關(guān)鍵字不管從使用還是效率上來說,都是有一定區(qū)別的。

使用上:

1、對(duì)重復(fù)結(jié)果的處理:UNION在進(jìn)行表鏈接后會(huì)篩選掉重復(fù)的記錄,而Union All則不會(huì)去除重復(fù)記錄。

2、對(duì)排序的處理:Union將會(huì)按照字段的順序進(jìn)行排序;UNION ALL只是將兩個(gè)結(jié)果合并后就返回,并不會(huì)進(jìn)行排序處理。

效率上:

從效率上說,UNION ALL的處理效率要比UNION高很多,所以,如果可以確認(rèn)合并的兩個(gè)結(jié)果集中,且不包含重復(fù)數(shù)據(jù)和不需要進(jìn)行排序的話,推薦使用UNION ALL。


相關(guān)閱讀:

不同場(chǎng)景下 MySQL 的遷移方案

MySQL FAQ系列整理


原文地址:https://blog.csdn.net/mine_song/article/details/70184072


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)