分享很少见很有用的SQL功能CORRESPONDING


Posted in MySQL onAugust 05, 2022

前言

我最近偶然发现了一个标准的SQL特性,令我惊讶的是,这个特性在HSQLDB中实现了。这个关键字是CORRESPONDING ,它可以和所有的集合操作一起使用,包括UNION 、INTERSECT 、和EXCEPT 。

让我们来看看sakila数据库它有3个表:

CREATE TABLE actor (
    actor_id integer NOT NULL PRIMARY KEY,
    first_name varchar(45) NOT NULL,
    last_name varchar(45) NOT NULL,
    last_update timestamp
);

CREATE TABLE customer (
    customer_id integer NOT NULL PRIMARY KEY,
    store_id smallint NOT NULL,
    first_name varchar(45) NOT NULL,
    last_name varchar(45) NOT NULL,
    email varchar(50),
    address_id smallint NOT NULL,
    create_date date NOT NULL,
    last_update timestamp,
    active boolean
);

CREATE TABLE staff (
    staff_id integer NOT NULL PRIMARY KEY,
    first_name varchar(45) NOT NULL,
    last_name varchar(45) NOT NULL,
    address_id smallint NOT NULL,
    email varchar(50),
    store_id smallint NOT NULL,
    active boolean NOT NULL,
    username varchar(16) NOT NULL,
    password varchar(40),
    last_update timestamp,
    picture blob
);

相似,但不相同。如果我们想从我们的数据库中获得所有的 "人 "呢?在任何普通的数据库产品中,有一种方法可以做到这一点:

SELECT first_name, last_name
FROM actor
UNION ALL
SELECT first_name, last_name
FROM customer
UNION ALL
SELECT first_name, last_name
FROM staff
ORDER BY first_name, last_name

结果可能看起来像这样:

|first_name|last_name|
|----------|---------|
|AARON     |SELBY    |
|ADAM      |GOOCH    |
|ADAM      |GRANT    |
|ADAM      |HOPPER   |
|ADRIAN    |CLARY    |
|AGNES     |BISHOP   |
|AL        |GARLAND  |
|ALAN      |DREYFUSS |
|...       |...      |

使用CORRESPONDING

现在,在HSQLDB中,以及在标准SQL中,你可以使用CORRESPONDING 来完成这种任务。比如说:

SELECT *
FROM actor
UNION ALL CORRESPONDING
SELECT *
FROM customer
UNION ALL CORRESPONDING
SELECT *
FROM staff
ORDER BY first_name, last_name

其结果是这样的:

|first_name|last_name|last_update            |
|----------|---------|-----------------------|
|AARON     |SELBY    |2006-02-15 04:57:20.000|
|ADAM      |GOOCH    |2006-02-15 04:57:20.000|
|ADAM      |GRANT    |2006-02-15 04:34:33.000|
|ADAM      |HOPPER   |2006-02-15 04:34:33.000|
|ADRIAN    |CLARY    |2006-02-15 04:57:20.000|
|AGNES     |BISHOP   |2006-02-15 04:57:20.000|
|AL        |GARLAND  |2006-02-15 04:34:33.000|
|ALAN      |DREYFUSS |2006-02-15 04:34:33.000|
|...       |...      |...                    |

那么,发生了什么?列FIRST_NAME,LAST_NAME, 和LAST_UPDATE 是这三个表所共有的。换句话说,如果你针对HSQLDB中的INFORMATION_SCHEMA ,运行这个查询:

SELECT column_name
FROM information_schema.columns
WHERE table_name = 'ACTOR'
INTERSECT
SELECT column_name
FROM information_schema.columns
WHERE table_name = 'CUSTOMER'
INTERSECT
SELECT column_name
FROM information_schema.columns
WHERE table_name = 'STAFF'

你得到的正是这3个列:

|COLUMN_NAME|
|-----------|
|FIRST_NAME |
|LAST_NAME  |
|LAST_UPDATE|

换句话说,CORRESPONDING ,在集合操作的子查询中创建列的交集(即 "共享列"),投影这些,并应用该投影的集合操作。在某种程度上,这类似于一个 [NATURAL JOIN](https://blog.jooq.org/impress-your-coworkers-with-a-sql-natural-full-outer-join/),后者也试图找到列的交集以产生一个连接谓词。然而,NATURAL JOIN ,然后投影所有的列(或列的联合),而不仅仅是共享的列。

使用CORRESPONDING BY

就像NATURAL JOIN ,这是个有风险的操作。只要一个子查询改变了它的投影(例如,由于表的列重命名),所有这些查询的结果也会改变,甚至可能不会产生语法错误,只是结果不同。

事实上,在上面的例子中,我们可能根本不关心那个LAST_UPDATE 列。它被意外地包含在UNION ALL 的集合操作中,就像NATURAL JOIN 会意外地使用LAST_UPDATE 来连接一样。

对于连接,我们可以使用JOIN .. USING (first_name, last_name) ,至少指定我们想通过哪一个共享列名来连接这两个表。使用CORRESPONDING ,我们可以为同样的目的提供可选的BY 子句:

SELECT *
FROM actor
UNION ALL CORRESPONDING BY (first_name, last_name)
SELECT *
FROM customer
UNION ALL CORRESPONDING BY (first_name, last_name)
SELECT *
FROM staff
ORDER BY first_name, last_name;

现在,这只产生了两个想要的列:

|first_name|last_name|
|----------|---------|
|AARON     |SELBY    |
|ADAM      |GOOCH    |
|ADAM      |GRANT    |
|ADAM      |HOPPER   |
|ADRIAN    |CLARY    |
|AGNES     |BISHOP   |
|AL        |GARLAND  |
|ALAN      |DREYFUSS |
|...       |...      |

事实上,这样一来,我们甚至可以有意义地使用INTERSECT和EXCEPT的语法,例如,找到与某个演员共享名字的客户:

SELECT *
FROM actor
INTERSECT CORRESPONDING BY (first_name, last_name)
SELECT *
FROM customer
ORDER BY first_name, last_name;

制作:

|first_name|last_name|
|----------|---------|
|JENNIFER  |DAVIS    |

到此这篇关于分享很少见很有用的SQL功能CORRESPONDING的文章就介绍到这了,更多相关SQL功能内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

MySQL 相关文章推荐
MySQL获取所有分类的前N条记录
May 07 MySQL
mysql外连接与内连接查询的不同之处
Jun 03 MySQL
MySQL 常见的数据表设计误区汇总
Jun 07 MySQL
Mysql 如何查询时间段交集
Jun 08 MySQL
MySQL中IF()、IFNULL()、NULLIF()、ISNULL()函数的使用详解
Jun 26 MySQL
解决Mysql的left join无效及使用的注意事项说明
Jul 01 MySQL
MySQL系列之十 MySQL事务隔离实现并发控制
Jul 02 MySQL
解决mysql的int型主键自增问题
Jul 15 MySQL
MySQL外键约束(FOREIGN KEY)案例讲解
Aug 23 MySQL
MySQL非空约束(not null)案例讲解
Aug 23 MySQL
MySQL基础快速入门知识总结(附思维导图)
Sep 25 MySQL
分析MySQL优化 index merge 后引起的死锁
Apr 19 MySQL
MySQL存储过程及语法详解
Aug 05 #MySQL
MySQL自定义函数及触发器
Aug 05 #MySQL
MySQL性能指标TPS+QPS+IOPS压测
Aug 05 #MySQL
Mysql中mvcc各场景理解应用
Aug 05 #MySQL
数据设计之权限的实现
一文解答什么是MySQL的回表
Aug 05 #MySQL
MySQL一劳永逸永久支持输入中文的方法实例
Aug 05 #MySQL
You might like
WordPress导航菜单的滚动和淡入淡出效果的实现要点
2015/12/14 PHP
php读取本地json文件的实例
2018/03/07 PHP
golang实现php里的serialize()和unserialize()序列和反序列方法详解
2018/10/30 PHP
Aster vs Newbee BO5 第三场2.19
2021/03/10 DOTA
jquery获取table中的某行全部td的内容方法
2013/03/08 Javascript
表格单元格交错着色实现思路及代码
2013/04/01 Javascript
一个简单的实现下拉框多选的插件可移植性比较好
2014/05/05 Javascript
生成二维码方法汇总
2014/12/26 Javascript
JavaScript判断页面加载完之后再执行预定函数的技巧
2016/05/17 Javascript
微信小程序 form组件详解
2016/10/25 Javascript
微信公众号开发 实现点击返回按钮就返回到聊天界面
2016/12/15 Javascript
JS获取本周周一,周末及获取任意时间的周一周末功能示例
2017/02/09 Javascript
jQuery+PHP+Mysql实现抽奖程序
2020/04/12 jQuery
jQuery remove()过滤被删除的元素(推荐)
2017/07/18 jQuery
使用Nodejs连接mongodb数据库的实现代码
2017/08/21 NodeJs
vue router-link传参以及参数的使用实例
2017/11/10 Javascript
jquery.param()实现数组或对象的序列化方法
2018/10/08 jQuery
JS执行控制之节流模式实例分析
2018/12/21 Javascript
tsconfig.json配置详解
2019/05/17 Javascript
原生JS实现相邻月份日历
2020/10/13 Javascript
vue仿携程轮播图效果(滑动轮播,下方高度自适应)
2021/02/11 Vue.js
Python多进程同步简单实现代码
2016/04/27 Python
python自动发送测试报告邮件功能的实现
2019/01/22 Python
selenium+python自动化测试之鼠标和键盘事件
2019/01/23 Python
33个Python爬虫项目实战(推荐)
2019/07/08 Python
详解pandas使用drop_duplicates去除DataFrame重复项参数
2019/08/01 Python
新学期开学演讲稿
2014/05/24 职场文书
党员对照检查材料整改措施思想汇报
2014/09/26 职场文书
机动车登记业务委托书
2014/10/08 职场文书
北京故宫的导游词
2015/01/31 职场文书
建筑工程挂靠协议书
2016/03/23 职场文书
简单了解 MySQL 中相关的锁
2021/05/25 MySQL
html5表单的required属性使用
2021/07/07 HTML / CSS
CSS实现隐藏搜索框功能(动画正反向序列)
2021/07/21 HTML / CSS
mysql的Buffer Pool存储及原理
2022/04/02 MySQL
Go语言 详解net的tcp服务
2022/04/14 Golang