MySQL 8.0新特性INTERSECT和EXCEPT用于集合运算

MySQL8.0.31 新版本的推出,MySQL增加了对SQL标准INTERSECT和EXCEPT运算符的支持。

1、INTERSECT

INTERSECT输出多个SELECT语句查询结果中的共有行。INTERSECT运算符是ANSI/ISO SQL标准的一部分(ISO/IEC 9075-2:2016(E))。

我们运行两个查询,第一个会列出ID是 1,2,3 记录,第二个会列出ID是 2,3,4记录。这两个单独的查询是:
在这里插入图片描述
we had two result sets T1 and T2:

  • T1 result set includes 1, 2, and 3.
  • T2 result set includes 2, 3, and 4.

The intersection of T1 and T2 result sets returns the distinct rows which are 2 and 3

(root@localhost)[(none)]> with t1 as (select 1 as id union all select 2 as id union all select 3 as id),
    ->  t2 as (select 2 as id union all select 3 as id union all select 4 as id)
    -> select id from t1 intersect select id from t2;
+----+
| id |
+----+
|  2 |
|  3 |
+----+
2 rows in set (0.02 sec)

2、EXCEPT

except输出在第一个select语句结果中存在但不在二个查询结果中的记录的行。
The following are the rules for combining the result sets of two queries in the above syntax:

The number and order of columns must be the same in both queries.

The data types of the corresponding columns must be the same or compatible.

The following picture shows the EXCEPT operation of the two result sets T1 and T2:

在这里插入图片描述

(root@localhost)[(none)]> with t1 as (select 1 as id union all select 2 as id union all select 3 as id),
-> t2 as (select 2 as id union all select 3 as id union all select 4 as id) 
-> select id from t1 except select id from t2;
+----+
| id |
+----+
|  1 |
+----+
1 row in set (0.00 sec)

3、MySQL 8.0及之前的版本中

在MySQL 8.0及之前的版本中,直接并不支持SQL标准中的INTERSECT和EXCEPT操作符,这两个操作符在SQL中用于集合运算,分别用来找出两个查询结果的交集和差集。但是,你可以通过其他方式来实现类似INTERSECT和EXCEPT的功能。

3.1、模拟INTERSECT

要模拟INTERSECT的行为,你可以使用INNER JOIN或者EXISTS子查询。但是,对于简单的交集查询,通常使用INNER JOIN的方式更为直观。

使用INNER JOIN模拟INTERSECT
假设你有两个表TableA和TableB,你想要找出在TableA.column1和TableB.column1中都存在的值,可以这样做

SELECT A.column1  
FROM TableA A  
  INNER JOIN TableB B ON A.column1 = B.column1;

如果这两个列来自不同的查询,你可以使用子查询或临时表/CTE(公用表表达式,MySQL 8.0支持)来模拟

WITH CTE_A AS (  
    SELECT column1 FROM (your_query_for_TableA)  
), CTE_B AS (  
    SELECT column1 FROM (your_query_for_TableB)  
)  
SELECT A.column1  
FROM CTE_A AS A
  INNER JOIN CTE_B AS B ON A.column1 = B.column1;

3.2、模拟EXCEPT

要模拟EXCEPT的行为,你可以使用LEFT JOIN或者NOT EXISTS子查询。使用LEFT JOIN的方式通常更为直接。

使用LEFT JOIN模拟EXCEPT
假设你仍然使用TableA和TableB,并且想要找出在TableA.column1中存在但在TableB.column1中不存在的值,可以这样做:

SELECT A.column1  
FROM TableA A  
  LEFT JOIN TableB B ON A.column1 = B.column1  
WHERE B.column1 IS NULL;

或者,如果你有两个不同的查询结果,你可以使用子查询或CTE来模拟

WITH CTE_A AS (  
    SELECT column1 FROM (your_query_for_TableA)  
), CTE_B AS (  
    SELECT column1 FROM (your_query_for_TableB)  
)  
SELECT A.column1  
FROM CTE_A AS A  
  LEFT JOIN CTE_B AS B ON A.column1 = B.column1  
WHERE B.column1 IS NULL;

4、注意事项

  • 当使用 INTERSECT 或 EXCEPT 时,两个查询的列数和列的数据类型必须兼容。这意味着两个查询必须选择相同数量的列,并且这些列在数据类型上必须能够相互比较。

  • 默认情况下,INTERSECT 和 EXCEPT 返回的结果集中的列没有特定的顺序。如果你需要结果按特定顺序返回,你应该使用 ORDER BY 子句。

  • 这两个操作符在处理大量数据时可能会比使用 JOIN 或其他集合操作更慢,因为 MySQL 需要分别执行两个查询,然后在内部对它们的结果集进行比较。因此,在性能敏感的应用程序中,建议仔细考虑查询的设计和优化。

  • 25
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值