MySQL?8.0新特性之集合操作符INTERSECT和EXCEPT
前言
最近幾年,MySQL 不斷致力于兼容 SQL 標(biāo)準(zhǔn)。例如 MySQL 8.0 中的窗口函數(shù)、通用表表達(dá)式、檢查約束等等。
最新發(fā)布的 MySQL 8.0.31 繼續(xù)對 SQL 語句進(jìn)行了增強(qiáng),提供了缺失已久的兩個集合操作符:INTERSECT 和 EXCEPT。
交集操作符(INTERSECT)
INTERSECT 操作符用于返回兩個查詢結(jié)果中的共同部分,即同時出現(xiàn)在第一個查詢結(jié)果和第二個查詢結(jié)果中的數(shù)據(jù),并且對最終結(jié)果進(jìn)行了去重操作。交集運算的示意圖如下:

其中,1 和 2 是兩個查詢中都存在的數(shù)據(jù);因此交集運算的結(jié)果只包含 1 和 2。
我們創(chuàng)建一個年度優(yōu)秀員工表(excellent_emp),用于演示集合操作:
CREATE TABLE excellent_emp(
year INT NOT NULL,
emp_id INTEGER NOT NULL,
CONSTRAINT pk_excellent_emp PRIMARY KEY (YEAR, emp_id)
);
INSERT INTO excellent_emp VALUES (2018, 9);
INSERT INTO excellent_emp VALUES (2018, 11);
INSERT INTO excellent_emp VALUES (2019, 9);
INSERT INTO excellent_emp VALUES (2019, 20);
以下示例用于查找 2018 年和 2019 年都是優(yōu)秀員工的員工編號:
SELECT emp_id
FROM excellent_emp
WHERE year = 2018
INTERSECT
SELECT emp_id
FROM excellent_emp
WHERE year = 2019;
emp_id|
------|
9|
其中,INTERSECT 表示交集運算。第一個查詢語句返回了 9 和 11,第二個查詢語句返回了 9 和 20,最終結(jié)果返回共同的 9。集合操作返回的字段名由第一個語句決定,此處兩個語句擁有相同的字段名(emp_id)。
對于 MySQL 5.7 以及之前的版本,以上示例可以改寫為等價的連接查詢:
SELECT t1.emp_id
FROM excellent_emp t1
JOIN excellent_emp t2
ON (t1.emp_id = t2.emp_id
AND t1.year = 2018
AND t2.year = 2019);
emp_id|
------|
9|
交集運算都可以改寫為等價的等值內(nèi)連接查詢。
INTERSECT 操作符的完整語法如下:
SELECT ... INTERSECT [ALL | DISTINCT] SELECT ... [INTERSECT [ALL | DISTINCT] SELECT ...]
ALL 選項表示保留查詢結(jié)果集中的重復(fù)記錄,DISTINCT 選項表示去除查詢結(jié)果集中的重復(fù)記錄,默認(rèn)選項為 DISTINCT。
另外,INTERSECT 操作符的優(yōu)先級比 UNION 和 EXCEPT 更高,因此以下兩種寫法等價:
TABLE r EXCEPT TABLE s INTERSECT TABLE t; TABLE r EXCEPT (TABLE s INTERSECT TABLE t);
關(guān)于 INTERSECT 操作符的更多信息,可以參考官方文檔。
差集操作符(EXCEPT)
EXCEPT 操作符用于返回出現(xiàn)在第一個查詢結(jié)果中,但不在第二個查詢結(jié)果中的記錄,并且對最終結(jié)果進(jìn)行了去重操作。差集運算的示意圖如下:

第一個查詢的結(jié)果中只有 3 沒有出現(xiàn)在第二個查詢的結(jié)果中,因此差集運算的結(jié)果只保留了 3。
以下語句查找 2019 年被評為優(yōu)秀,但是 2018 年不是優(yōu)秀的員工:
SELECT emp_id
FROM excellent_emp
WHERE year = 2019
EXCEPT
SELECT emp_id
FROM excellent_emp
WHERE year = 2018;
emp_id|
------|
20|
查詢結(jié)果顯示,只有 20 號員工是 2019 年新晉的優(yōu)秀員工。
對于 MySQL 5.7 以及之前的版本,以上示例可以改寫為等價左外連接查詢:
SELECT t1.emp_id
FROM excellent_emp t1
LEFT JOIN excellent_emp t2 ON (t1.emp_id = t2.emp_id AND t2.year = 2018)
WHERE t1.year = 2019
AND t2.emp_id IS NULL;
emp_id|
------|
20|
其中,左外連接返回了所有的優(yōu)秀員工;然后利用 WHERE 條件找出其中 2019 年是優(yōu)秀但 2018 年不是優(yōu)秀的員工。
EXCEPT 操作符的完整語法如下:
SELECT ... EXCEPT [ALL | DISTINCT] SELECT ... [EXCEPT [ALL | DISTINCT] SELECT ...]
ALL 選項表示保留查詢結(jié)果集中的重復(fù)記錄,DISTINCT 選項表示去除查詢結(jié)果集中的重復(fù)記錄,默認(rèn)選項為 DISTINCT。
關(guān)于 INTERSECT 操作符的更多信息,可以參考官方文檔。
總結(jié)
到此這篇關(guān)于MySQL 8.0新特性之集合操作符INTERSECT和EXCEPT的文章就介紹到這了,更多相關(guān)MySQL8.0 INTERSECT和EXCEPT內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mysql 根據(jù)一個表數(shù)據(jù)更新另一個表的某些字段(sql語句)
這篇文章主要介紹了Mysql 根據(jù)一個表數(shù)據(jù)更新另一個表的某些字段,本文給出了sql語句,感興趣的朋友可以跟隨腳本之家小編一起學(xué)習(xí)吧2018-05-05
以數(shù)據(jù)庫字段分組顯示數(shù)據(jù)的sql語句(詳細(xì)介紹)
本篇文章是對以數(shù)據(jù)庫字段分組顯示數(shù)據(jù)的sql語句進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
mysql數(shù)據(jù)庫備份及恢復(fù)命令 mysqldump,source的用法
mysql數(shù)據(jù)庫備份及恢復(fù)命令 mysqldump,source的用法,需要的朋友可以參考下。2011-02-02
MySQL運維實戰(zhàn)使用RPM進(jìn)行安裝部署
這篇文章主要為大家介紹了MySQL運維實戰(zhàn)使用RPM進(jìn)行安裝部署實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
windows server2016安裝MySQL5.7.19解壓縮版教程詳解
本篇文章給大家記錄了MySQL 5.7.19 winx64解壓縮版安裝教程,非常不錯,具有參考借鑒價值,需要的的朋友參考下吧2017-08-08
MYSQL中統(tǒng)計查詢結(jié)果總行數(shù)的便捷方法省去count(*)
查看手冊后發(fā)現(xiàn)SQL_CALC_FOUND_ROWS關(guān)鍵詞的作用是在查詢時統(tǒng)計滿足過濾條件后的結(jié)果的總數(shù)(不受 Limit 的限制)具體使用如下,感興趣的朋友可以學(xué)習(xí)下2013-07-07

