乐趣区

关于mysql:新特性解读-MySQL-80-的交集和差集介绍

作者:杨涛涛

资深数据库专家,专研 MySQL 十余年。善于 MySQL、PostgreSQL、MongoDB 等开源数据库相干的备份复原、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相干技术支持、MySQL 相干课程培训等工作。

本文起源:原创投稿

* 爱可生开源社区出品,原创内容未经受权不得随便应用,转载请分割小编并注明起源。


MySQL 8.0 最新小版本(8.0.31)反对规范 SQL 的 intersect(交加)和 except(差集)操作。

交加:也就是返回两个后果集的相交局部,也即左侧和右侧同时存在的记录。

差集:也就是返回两个后果集中左侧存在同时右侧不存在的记录。

之前在做其余数据库往 MySQL 迁徙的时候,常常遇到这样的操作。因为 MySQL 始终以来不反对这两类操作符,个别得想方法避开或者是通过其余办法来实现。

比方在 MySQL 5.7.x 中,想要实现如下两个需要:

第一、求表 t1 和表 t2 的交加,并且后果要去重;

第二、求表 t1 和表 t2 的差集,并且后果也要去重。

简略创立表 t1、表 t2,并且插入几条样例数据:

<mysql:5.7.34:(ytt)> create table t1(c1 int);
Query OK, 0 rows affected (0.02 sec)

<mysql:5.7.34:(ytt)> create table t2 like t1;
Query OK, 0 rows affected (0.02 sec)

<mysql:5.7.34:(ytt)> insert t1 values (10),(20),(20),(30),(40),(40),(50);
Query OK, 7 rows affected (0.00 sec)
Records: 7  Duplicates: 0  Warnings: 0

<mysql:5.7.34:(ytt)> insert t2 values (10),(30),(30),(50),(50),(70),(90);
Query OK, 7 rows affected (0.02 sec)
Records: 7  Duplicates: 0  Warnings: 0 
<mysql:5.7.34:(ytt)> select * from t1;
+------+
| c1   |
+------+
|   10 |
|   20 |
|   20 |
|   30 |
|   40 |
|   40 |
|   50 |
+------+
7 rows in set (0.00 sec)

<mysql:5.7.34:(ytt)> select * from t2;
+------+
| c1   |
+------+
|   10 |
|   30 |
|   30 |
|   50 |
|   50 |
|   70 |
|   90 |
+------+
7 rows in set (0.00 sec)

咱们来实现这两个需要:

  1. 求去重后的交加:两表内联、去重!
<mysql:5.7.34:(ytt)> select distinct t1.c1 from t1 join t2 using(c1);
+------+
| c1   |
+------+
|   10 |
|   30 |
|   50 |
+------+
3 rows in set (0.00 sec)
  1. 求去重后的差集:两表左外联,去重,并且保留右表关联键为 NULL 的记录。
<mysql:5.7.34:(ytt)> select distinct t1.c1 from t1 left join t2 using(c1) where t2.c1 is null;
+------+
| c1   |
+------+
|   20 |
|   40 |
+------+
2 rows in set (0.00 sec)

在最新版本 MySQL 8.0.31 中,间接用 intersect 和 except 两个新操作符即可,写起来非常简单。

创立好同样的表构造和数据,用 intersect 来求交加:

<mysql:8.0.31:(ytt)>table t1 intersect table t2;
+------+
| c1   |
+------+
|   10 |
|   30 |
|   50 |
+------+
3 rows in set (0.00 sec)

用 except 来求差集:

<mysql:8.0.31:(ytt)>table t1 except table t2;
+------+
| c1   |
+------+
|   20 |
|   40 |
+------+
2 rows in set (0.00 sec)

intersect 和 except 操作符默认去重。比方须要保留原始后果,则能够带上 all 关键词:如下求两表差集的后果会保留所有符合条件的记录。

<mysql:8.0.31:(ytt)>table t1 except all table t2;
+------+
| c1   |
+------+
|   20 |
|   20 |
|   40 |
|   40 |
+------+
4 rows in set (0.00 sec)
退出移动版