分享很少见很有用的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 联合查询优化机制
May 10 MySQL
详细聊聊MySQL中慢SQL优化的方向
Aug 30 MySQL
mysql中varchar类型的日期进行比较、排序等操作的实现
Nov 17 MySQL
分享mysql的current_timestamp小坑及解决
Nov 27 MySQL
Mysql事务索引知识汇总
Mar 17 MySQL
MySQL读取JSON转换的方式
Mar 18 MySQL
MySQL分区表管理命令汇总
Mar 21 MySQL
MySQL学习必备条件查询数据
Mar 25 MySQL
MySQL RC事务隔离的实现
Mar 31 MySQL
MySQL 数据 data 基本操作
May 04 MySQL
Mysql数据库group by原理详解
Jul 07 MySQL
DQL数据查询语句使用示例
Dec 24 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
文件上传程序的全部源码
2006/10/09 PHP
使用php+apc实现上传进度条且在IE7下不显示的问题解决方法
2013/04/25 PHP
浅析php数据类型转换
2014/01/09 PHP
Yii多表联合查询操作详解
2016/06/02 PHP
PHP生成腾讯云COS接口需要的请求签名
2018/05/20 PHP
js变量以及其作用域详解
2020/07/18 Javascript
jQuery-Easyui 1.2 实现多层菜单效果的代码
2012/01/13 Javascript
js判断undefined变量类型使用typeof
2013/06/03 Javascript
javascript鼠标滑动评分控件完整实例
2015/05/13 Javascript
jquery预加载图片的方法
2015/05/27 Javascript
基于JavaScript实现简单的随机抽奖小程序
2016/01/05 Javascript
vue组件父子间通信之综合练习(聊天室)
2017/11/07 Javascript
微信小程序实现点击按钮修改字体颜色功能【附demo源码下载】
2017/12/05 Javascript
zTree 树插件实现全国五级地区点击后加载的示例
2018/02/05 Javascript
Vue press 支持图片放大功能的实例代码
2018/11/09 Javascript
[53:44]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Magma BO3 第一场 1月31日
2021/03/11 DOTA
python爬虫入门教程--利用requests构建知乎API(三)
2017/05/25 Python
Python使用三种方法实现PCA算法
2017/12/12 Python
Python实现PS图像调整黑白效果示例
2018/01/25 Python
Python实现获取汉字偏旁部首的方法示例【测试可用】
2018/12/18 Python
通过python的matplotlib包将Tensorflow数据进行可视化的方法
2019/01/09 Python
详解Python中is和==的区别
2019/03/21 Python
python sorted方法和列表使用解析
2019/11/18 Python
Python实现多线程下载脚本的示例代码
2020/04/03 Python
python中sympy库求常微分方程的用法
2020/04/28 Python
解决H5的a标签的download属性下载service上的文件出现跨域问题
2019/07/16 HTML / CSS
美国在线乐器和设备商店:Musician’s Friend
2018/07/06 全球购物
爱岗敬业演讲稿范文
2014/01/14 职场文书
物理教学随笔感言
2014/02/22 职场文书
优秀的个人求职信范文
2014/05/09 职场文书
年终奖发放方案
2014/06/02 职场文书
我的职业生涯规划:打造自己的运动帝国
2014/09/18 职场文书
四风对照检查剖析材料
2014/10/07 职场文书
地道战观后感500字
2015/06/04 职场文书
Python turtle实现贪吃蛇游戏
2021/06/18 Python
Android存储中最基本的文件存储方式
2022/04/30 Java/Android