分享很少见很有用的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 05 MySQL
Mysql 如何批量插入数据
Apr 06 MySQL
Mysql 性能监控及调优
Apr 06 MySQL
MySQL创建索引需要了解的
Apr 08 MySQL
mysql在项目中怎么选事务隔离级别
May 25 MySQL
Mysql 如何查询时间段交集
Jun 08 MySQL
Mysql数据库值的添加、修改、删除及清空操作实例
Jun 20 MySQL
mysql中varchar类型的日期进行比较、排序等操作的实现
Nov 17 MySQL
一次SQL如何查重及去重的实战记录
Mar 13 MySQL
mysql 生成连续日期及变量赋值
Mar 20 MySQL
mysql 获取时间方式
Mar 20 MySQL
MySQL主从切换的超详细步骤
Jun 28 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 IPV6正则表达式验证代码
2010/02/16 PHP
php删除与复制文件夹及其文件夹下所有文件的实现代码
2013/01/23 PHP
PHP调用C#开发的dll类库方法
2014/07/28 PHP
基于JQuery的6个Tab选项卡插件
2010/09/03 Javascript
js下关于onmouseout、事件冒泡的问题经验小结
2010/12/09 Javascript
js对数字的格式化使用说明
2011/01/12 Javascript
jquery的选择器的使用技巧之如何选择input框
2013/09/22 Javascript
window.onload和$(function(){})的区别介绍
2013/10/30 Javascript
JS小功能(onmouseover实现选择月份)实例代码
2013/11/28 Javascript
js改变html的原有内容实现方法
2016/10/05 Javascript
js表单登陆验证示例
2016/10/19 Javascript
基于JS实现翻书效果的页面切换样式
2017/02/16 Javascript
使用get方式提交表单在地址栏里面不显示提交信息
2017/02/21 Javascript
vue基于mint-ui的城市选择3级联动的示例
2017/10/25 Javascript
微信小程序错误this.setData报错及解决过程
2019/09/18 Javascript
微信小程序制作扭蛋机代码实例
2019/09/24 Javascript
JS Web Flex弹性盒子模型代码实例
2020/03/10 Javascript
python读取浮点数和读取文本文件示例
2014/05/06 Python
用Python代码来绘制彭罗斯点阵的教程
2015/04/03 Python
Python scikit-learn 做线性回归的示例代码
2017/11/01 Python
python MySQLdb使用教程详解
2018/03/20 Python
Django 日志配置按日期滚动的方法
2019/01/31 Python
对python中字典keys,values,items的使用详解
2019/02/03 Python
Python常见的pandas用法demo示例
2019/03/16 Python
ubuntu 安装pyqt5和卸载pyQt5的方法
2020/03/24 Python
TensorFlow的环境配置与安装教程详解(win10+GeForce GTX1060+CUDA 9.0+cuDNN7.3+tensorflow-gpu 1.12.0+python3.5.5)
2020/06/22 Python
详解python百行有效代码实现汉诺塔小游戏(简约版)
2020/10/30 Python
俄罗斯外国汽车和国产汽车配件网上商店:Движком
2020/04/19 全球购物
产品推广策划方案
2014/05/10 职场文书
债务纠纷委托书
2014/08/30 职场文书
忠诚奉献演讲稿
2014/09/12 职场文书
慰问信模板
2015/02/14 职场文书
2015年党员创先争优公开承诺书
2015/04/27 职场文书
《我们的民族小学》教学反思
2016/02/19 职场文书
关于html选择框创建占位符的问题
2021/06/09 HTML / CSS
人民币符号
2022/02/17 杂记