分享很少见很有用的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 INSERT INTO语句
May 26 MySQL
MySQL中使用or、in与union all在查询命令下的效率对比
May 26 MySQL
MySQL里面的子查询的基本使用
Aug 02 MySQL
mysql配置SSL证书登录的实现
Sep 04 MySQL
MySQL中几种插入和批量语句实例详解
Sep 14 MySQL
一篇文章看懂MySQL主从复制与读写分离
Nov 07 MySQL
解决Mysql多行子查询的使用及空值问题
Jan 22 MySQL
mysql聚集索引、辅助索引、覆盖索引、联合索引的使用
Feb 12 MySQL
MySQL的prepare使用以及遇到的bug
May 11 MySQL
MySQL慢查询中的commit慢和binlog中慢事务的区别
Jun 16 MySQL
MySQL事务的隔离级别详情
Jul 15 MySQL
面试官问我Mysql的存储引擎了解多少
Aug 05 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 function用法如何递归及return和echo区别
2014/03/07 PHP
destoon安全设置中需要设置可写权限的目录及文件
2014/06/21 PHP
php使用Image Magick将PDF文件转换为JPG文件的方法
2015/04/01 PHP
php curl 获取https请求的2种方法
2015/04/27 PHP
smarty中常用方法实例总结
2015/08/07 PHP
JS俄罗斯方块,包含完整的设计理念
2010/12/11 Javascript
JavaScript中的this关键字介绍与使用实例
2013/06/21 Javascript
jQuery 仿百度输入标签插件附效果图
2014/07/04 Javascript
JavaScript中document对象使用详解
2015/01/06 Javascript
JavaScript判断变量是否为空的自定义函数分享
2015/01/31 Javascript
vue.js学习之递归组件
2016/12/13 Javascript
nodejs实现发出蜂鸣声音(系统报警声)的方法
2017/01/18 NodeJs
jQuery简单实现向列表动态添加新元素的方法示例
2017/12/25 jQuery
关于echarts在节点显示动态数据及添加提示文本所遇到的问题
2018/04/20 Javascript
基于Vue实现图片在指定区域内移动的思路详解
2018/11/11 Javascript
Python中查看文件名和文件路径
2017/03/31 Python
Python人脸识别初探
2017/12/21 Python
JSON文件及Python对JSON文件的读写操作
2018/10/07 Python
Python 按字典dict的键排序,并取出相应的键值放于list中的实例
2019/02/12 Python
钉钉群自定义机器人消息Python封装的实例
2019/02/20 Python
Python基于WordCloud制作词云图
2019/11/29 Python
Python列表list操作相关知识小结
2020/01/29 Python
对tensorflow中tf.nn.conv1d和layers.conv1d的区别详解
2020/02/11 Python
Python远程linux执行命令实现
2020/11/11 Python
python help函数实例用法
2020/12/06 Python
HTML5上传文件显示进度的实现代码
2012/08/30 HTML / CSS
俄罗斯名牌服装网上商店:UNIQUE FABRIC
2019/07/25 全球购物
SQL语言面试题
2013/08/27 面试题
结构和类有什么异同
2012/07/16 面试题
中科软笔试题和面试题
2014/10/07 面试题
给校长的建议书300字
2014/05/16 职场文书
服务标语大全
2014/06/18 职场文书
大学生党员个人剖析材料
2014/10/08 职场文书
2014年收银工作总结
2014/11/13 职场文书
2015年董事长秘书工作总结
2015/07/23 职场文书
关于开学的感想
2015/08/10 职场文书