分享很少见很有用的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 Show Profile
Apr 05 MySQL
MySQL update set 和 and的区别
May 08 MySQL
MySQL连接查询你真的学会了吗?
Jun 02 MySQL
MySQL中存储时间的最佳实践指南
Jul 01 MySQL
MySQL 四种连接和多表查询详解
Jul 16 MySQL
为什么MySQL 删除表数据 磁盘空间还一直被占用
Oct 16 MySQL
MySQL学习之基础命令实操总结
Mar 19 MySQL
CentOS 7安装mysql5.7使用XtraBackUp备份工具命令详解
Apr 12 MySQL
mysql5.5中文乱码问题解决的有用方法
May 30 MySQL
MySQL示例讲解数据库约束以及表的设计
Jun 16 MySQL
Mysql中mvcc各场景理解应用
Aug 05 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
无数据库的详细域名查询程序PHP版(4)
2006/10/09 PHP
聊天室php&mysql(二)
2006/10/09 PHP
php连接Access数据库错误及解决方法
2013/06/20 PHP
简单的php新闻发布系统教程
2014/05/09 PHP
php注册审核重点解析(数据访问)
2017/05/23 PHP
Javascript 类与静态类的实现
2010/04/01 Javascript
基于jquery跨浏览器显示的file上传控件
2011/10/24 Javascript
浅谈checkbox的一些操作(实战经验)
2013/11/20 Javascript
使用原生js封装webapp滑动效果(惯性滑动、滑动回弹)
2014/05/06 Javascript
Javascript window对象详解
2014/11/12 Javascript
JavaScript开发人员的10个关键习惯小结
2014/12/05 Javascript
在父页面得到zTree已选中的节点的方法
2015/02/12 Javascript
原生js实现移动端瀑布流式代码示例
2015/12/18 Javascript
原生JavaScript制作微博发布面板效果
2016/03/11 Javascript
解决vue router使用 history 模式刷新后404问题
2017/07/19 Javascript
Angular中响应式表单的三种更新值方法详析
2017/08/22 Javascript
详解ECMAScript2019/ES10新属性
2019/12/06 Javascript
[02:56]DOTA2英雄基础教程 巨魔战将
2013/12/10 DOTA
python 制作自定义包并安装到系统目录的方法
2018/10/27 Python
python 将字符串完成特定的向右移动方法
2019/06/11 Python
通过pycharm使用git的步骤(图文详解)
2019/06/13 Python
pytorch 模型可视化的例子
2019/08/17 Python
Python3读取和写入excel表格数据的示例代码
2020/06/09 Python
python利用递归方法实现求集合的幂集
2020/09/07 Python
Python web框架(django,flask)实现mysql数据库读写分离的示例
2020/11/18 Python
CSS3实现时间轴效果
2016/07/11 HTML / CSS
美国著名的品牌折扣店:Burlington
2017/06/08 全球购物
UDP协议功能
2013/01/06 面试题
护理专业学生的求职信范文
2013/12/11 职场文书
2015年幼儿园个人工作总结
2015/04/25 职场文书
麦田里的守望者读书笔记
2015/06/30 职场文书
网络研修随笔感言
2015/11/18 职场文书
初中美术教学反思
2016/02/17 职场文书
nginx里的rewrite跳转的实现
2021/03/31 Servers
解决Goland 同一个package中函数互相调用的问题
2021/05/06 Golang
Java设计模式之享元模式示例详解
2022/03/03 Java/Android