分享很少见很有用的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主从复制断开的常用修复方法
Apr 07 MySQL
mysql的MVCC多版本并发控制的实现
Apr 14 MySQL
MySQL官方导出工具mysqlpump的使用
May 21 MySQL
Mysql数据库命令大全
May 26 MySQL
详解MySQL中的pid与socket
Jun 15 MySQL
mysql优化之query_cache_limit参数说明
Jul 01 MySQL
MySQL系列之九 mysql查询缓存及索引
Jul 02 MySQL
Node-Red实现MySQL数据库连接的方法
Aug 07 MySQL
mysql 8.0.27 绿色解压版安装教程及配置方法
Apr 20 MySQL
Mysql 文件配置解析介绍
May 06 MySQL
MySQL 数据库 增删查改、克隆、外键 等操作
May 11 MySQL
MySQL表字段数量限制及行大小限制详情
Jul 23 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
php实现的双向队列类实例
2014/09/24 PHP
php 时间time与日期date之间的使用详解及区别
2016/11/07 PHP
laravel 框架实现无限级分类的方法示例
2019/10/31 PHP
Node.js编程中客户端Session的使用详解
2015/06/23 Javascript
使用BootStrap实现用户登录界面UI
2016/08/10 Javascript
JS简单去除数组中重复项的方法
2016/09/13 Javascript
AngularJS入门教程之Cookies读写操作示例
2016/11/02 Javascript
jQuery实现两个select控件的互移操作
2016/12/22 Javascript
AngularJS中table表格基本操作示例
2017/10/10 Javascript
nodejs async异步常用函数总结(推荐)
2017/11/17 NodeJs
详解如何用模块化的方式写vuejs
2017/12/16 Javascript
vue主动刷新页面及列表数据删除后的刷新实例
2018/09/16 Javascript
玩转Koa之核心原理分析
2018/12/29 Javascript
Vue+Django项目部署详解
2019/05/30 Javascript
JavaScript实现轮播图特效
2020/04/10 Javascript
python 2.6.6升级到python 2.7.x版本的方法
2016/10/09 Python
python实现邮件自动发送
2019/08/10 Python
简单了解python协程的相关知识
2019/08/31 Python
Python整数与Numpy数据溢出问题解决
2019/09/11 Python
Python3.7安装keras和TensorFlow的教程图解
2020/06/18 Python
python多项式拟合之np.polyfit 和 np.polyld详解
2020/02/18 Python
解决python3插入mysql时内容带有引号的问题
2020/03/02 Python
python pyqtgraph 保存图片到本地的实例
2020/03/14 Python
Python pytesseract验证码识别库用法解析
2020/06/29 Python
scrapy处理python爬虫调度详解
2020/11/23 Python
在HTML5中如何使用CSS建立不可选的文字
2014/10/17 HTML / CSS
HTML5的video标签的浏览器兼容性增强方案分享
2016/05/19 HTML / CSS
土建资料员岗位职责
2014/01/04 职场文书
创建卫生先进单位实施方案
2014/03/10 职场文书
反邪教标语
2014/06/23 职场文书
护士工作失误检讨书
2014/09/14 职场文书
公务员上班玩游戏检讨书
2014/09/17 职场文书
体育教师个人总结
2015/02/09 职场文书
出生证明格式
2015/06/15 职场文书
Mysql查询时间区间日期列表,不会由于数据表数据影响
2022/04/19 MySQL
SQL Server使用T-SQL语句批处理
2022/05/20 SQL Server