分享很少见很有用的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 root密码的重置方法
Apr 21 MySQL
Mysql 用户权限管理实现
May 25 MySQL
MySQL中存储时间的最佳实践指南
Jul 01 MySQL
MySQL系列之五 视图、存储函数、存储过程、触发器
Jul 02 MySQL
MySQL外键约束(FOREIGN KEY)案例讲解
Aug 23 MySQL
详细聊聊关于Mysql联合查询的那些事儿
Oct 24 MySQL
SQL基础的查询语句
Nov 11 MySQL
mysql下的max_allowed_packet参数设置详解
Feb 12 MySQL
如何创建一个创建MySQL数据库中的datetime类型
Mar 21 MySQL
WINDOWS 64位 下安装配置mysql8.0.25最详细的教程
Mar 22 MySQL
MySql如何将查询的出来的字段进行转换
Jun 14 MySQL
MySQL导致索引失效的几种情况
Jun 25 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
解析dedecms空间迁移步骤详解
2013/05/15 PHP
解读PHP的Yii框架中请求与响应的处理流程
2016/03/17 PHP
laravel框架数据库配置及操作数据库示例
2019/10/10 PHP
关于javascript DOM事件模型的两件事
2010/07/22 Javascript
JQuery浮动DIV提示信息并自动隐藏的代码
2010/08/29 Javascript
javascript中删除指定数组中指定的元素的代码
2011/02/12 Javascript
取得窗口大小 兼容所有浏览器的js代码
2011/08/09 Javascript
EasyUI的treegrid组件动态加载数据问题的解决办法
2011/12/11 Javascript
倒记时60刷新网页的js代码
2014/02/18 Javascript
javascipt:filter过滤介绍及使用
2014/09/10 Javascript
JavaScript事件委托用法分析
2015/01/24 Javascript
javaScript中Math()函数注意事项
2015/06/18 Javascript
前端微信支付js代码
2016/07/25 Javascript
BOM系列第一篇之定时器setTimeout和setInterval
2016/08/17 Javascript
AngularJS指令与指令之间的交互功能示例
2016/12/14 Javascript
Javascript基础回顾之(二) js作用域
2017/01/31 Javascript
如何理解Vue的render函数的具体用法
2017/08/30 Javascript
JQuery实现table中tr上移下移的示例(超简单)
2018/01/08 jQuery
JS使用setInterval实现的简单计时器功能示例
2018/04/19 Javascript
微信小程序 setData 对 data数据影响问题
2019/04/18 Javascript
仿ElementUI实现一个Form表单的实现代码
2019/04/23 Javascript
VUE使用axios调用后台API接口的方法
2020/08/03 Javascript
[44:58]2018DOTA2亚洲邀请赛 4.5 淘汰赛 LGD vs Liquid 第二场
2018/04/06 DOTA
python检测服务器是否正常
2014/02/16 Python
用Python计算三角函数之atan()方法的使用
2015/05/15 Python
Python爬虫实例扒取2345天气预报
2018/03/04 Python
Django项目实战之用户头像上传与访问的示例
2018/04/21 Python
python列表插入append(), extend(), insert()用法详解
2019/09/14 Python
python脚本实现mp4中的音频提取并保存在原目录
2020/02/27 Python
Python描述符descriptor使用原理解析
2020/03/21 Python
基于python实现简单网页服务器代码实例
2020/09/14 Python
ZWILLING双立人英国网上商店:德国刀具锅具厨具品牌
2018/05/15 全球购物
Nike瑞典官方网站:Nike.com (SE)
2018/11/26 全球购物
意大利网上购书网站:Libraccio.it
2021/02/03 全球购物
鲁冰花观后感
2015/06/10 职场文书
2015暑期社会实践个人总结
2015/07/13 职场文书