当前位置:网站首页>一个很少见但很有用的SQL功能
一个很少见但很有用的SQL功能
2022-08-02 21:49:00 【wadfdhsajd】
我最近偶然发现了一个标准的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 |
复制代码其他方言
我以前没有在其他方言中多次遇到过这种语法。也许,它在将来会运到PostgreSQL中。Vik Fearing已经在做一个分支了:
小伙伴们有兴趣想了解内容和更多相关学习资料的请点赞收藏+评论转发+关注我,后面会有很多干货。
我有一些面试题、架构、设计类资料可以说是程序员面试必备!所有资料都整理到网盘了,需要的话欢迎下载!私信我回复【07】即可免费获取

链接:https://juejin.cn/post/7126351838349099022
边栏推荐
- 增删改查这么多年,最后栽在MySQL的架构设计上!
- 【DEBUG】ImportError: Unable to import required dependencies: numpy: DLL load failed: 找不到指定的模块。
- 双轴晶体中的锥形折射
- I interviewed a 985 graduate, and I will never forget the expression when answering the "performance tuning" question
- 总结嵌入式C语言难点(2部分)
- go 序列化与反序列化
- 采用QT进行OpenGL开发(三)着色器编程
- [TypeScript] Deep Learning of TypeScript Classes (Part 1)
- 「X」to「Earn」:赛道现状与破局思路
- H5网页播放器EasyPlayer.js播放器界面的加载效果无法消失是什么原因?
猜你喜欢
随机推荐
【DEBUG】ImportError: Unable to import required dependencies: numpy: DLL load failed: 找不到指定的模块。
七夕到了——属于程序员的浪漫
In-depth study TypeScript TypeScript 】 【 class (under)
MySQL 用id分库使用name查询
Command line startup FAQs and solutions
How many ways do you know the singleton pattern?
SSM integration steps (emphasis)
Swin Transformer 论文精读,并解析其模型结构
JS 包装类 Math对象 round max() min() random
Summary of @Transactional transaction invocation and effective scenarios
hi!Don't look at how to SAO gas dye-in-the-wood in MySQL?
Ansible安装与配置
若依集成minio实现分布式文件存储
Ansible installation and configuration
牛客刷题:数组排序
The only way to go from a monthly salary of 10k to 30k: automated testing
UDP (User Datagram Protocol)
YAML文件格式
同样月薪6K,为什么同事跳槽月薪翻倍,而你只涨了1000?
[c] Detailed explanation of operators (1)









