分享很少见很有用的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 查询速度慢的原因
May 25 MySQL
Mysql基础知识点汇总
May 26 MySQL
MySQL注入基础练习
May 30 MySQL
MySQL8.0无法启动3534的解决方法
Jun 03 MySQL
MySQL中IF()、IFNULL()、NULLIF()、ISNULL()函数的使用详解
Jun 26 MySQL
Mysql中调试存储过程最简单的方法
Jun 30 MySQL
MySQL中utf8mb4排序规则示例
Aug 02 MySQL
mysql的Buffer Pool存储及原理
Apr 02 MySQL
MySQ InnoDB和MyISAM存储引擎介绍
Apr 26 MySQL
详解Mysq MVCC多版本的并发控制
Apr 29 MySQL
MySQL数据库实验之 触发器和存储过程
Jun 21 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 版获取重定向后的地址(代码)
2013/06/26 PHP
js宝典学习笔记(上)
2007/01/10 Javascript
JavaScript新增样式规则(推荐)
2016/07/19 Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
2016/09/17 Javascript
IONIC自定义subheader的最佳解决方案
2016/09/22 Javascript
微信小程序 定位到当前城市实现实例代码
2017/02/23 Javascript
vue 使用element-ui中的Notification自定义按钮并实现关闭功能及如何处理多个通知
2019/08/17 Javascript
vue.js实现三级菜单效果
2019/10/19 Javascript
微信小程序工具函数封装
2019/10/28 Javascript
vue+element实现图片上传及裁剪功能
2020/06/29 Javascript
Python内置的字符串处理函数整理
2013/01/29 Python
python定时采集摄像头图像上传ftp服务器功能实现
2013/12/23 Python
python数据结构之图的实现方法
2015/07/08 Python
判断网页编码的方法python版
2016/08/12 Python
Python根据文件名批量转移图片的方法
2018/10/21 Python
Django CBV类的用法详解
2019/07/26 Python
django框架单表操作之增删改实例分析
2019/12/16 Python
解决pyCharm中 module 调用失败的问题
2020/02/12 Python
在tensorflow下利用plt画论文中loss,acc等曲线图实例
2020/06/15 Python
PyQt5多线程防卡死和多窗口用法的实现
2020/09/15 Python
Python基于Webhook实现github自动化部署
2020/11/28 Python
解决pycharm修改代码后第一次运行不生效的问题
2021/02/06 Python
CSS3 3D制作实战案例分析
2016/09/18 HTML / CSS
伊芙丽官方旗舰店:中国淑女一线品牌
2017/12/01 全球购物
PHP笔试题
2012/02/22 面试题
C++:局部变量能否和全局变量重名
2014/03/03 面试题
自动化专业毕业生自荐信
2013/11/01 职场文书
高三高考决心书
2014/03/11 职场文书
岗位廉政承诺书
2014/03/27 职场文书
出国留学经济担保书
2014/04/01 职场文书
“四风”问题对照检查材料思想汇报
2014/09/16 职场文书
师德师风自查材料
2014/10/14 职场文书
房屋产权共有协议书范本
2014/11/03 职场文书
2015年世界粮食日演讲稿
2015/03/20 职场文书
2015年学校总务处工作总结
2015/05/19 职场文书
Django中session进行权限管理的使用
2021/07/09 Python