当前位置:网站首页>Detailed guide to compare two tables using natural full join in SQL
Detailed guide to compare two tables using natural full join in SQL
2022-07-31 13:58:00 【DebugUsery】
在SQL中,There are several ways to compare two similar tables.假设PostgreSQL的语法,We might have such a pattern:
CREATE TABLE t1 (a INT, b INT, c INT);
CREATE TABLE t2 (a INT, b INT, c INT);
INSERT INTO t1 VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9);
INSERT INTO t2 VALUES (4, 5, 6), (7, 8, 9), (10, 11, 12);
复制代码
现在可以按照Chris Saxon的建议,使用UNION
和EXCEPT
:
You can compare two tables in the following way
t1减去t2联合t2减去t1
有一个更好的方法,You query each table once......But you need to list all the columns
幸运的是,@StewAshtonA neat package has been built,为你生成#SQL:)https://t.co/7OroPV6JdY
- Chris Saxon (@ChrisRSaxon)2020年8月5日
在PostgreSQL中,我们可以这样写:
(TABLE t1 EXCEPT TABLE t2)
UNION
(TABLE t2 EXCEPT TABLE t1)
ORDER BY a, b, c
复制代码
注意,TABLE x
只是标准的SQL,而PostgreSQL则是SELECT * FROM x
的语法糖.我们会得到:
a |b |c |
--|--|--|
1| 2| 3|
10|11|12|
复制代码
不幸的是,This requires two accesses to each table.Can we do it with an access?
Use natural full connection
是的!使用.使用NATURAL FULL JOIN
,This is another rare use case for this esoteric operator. 假设没有NULL值,我们可以这样写:
SELECT *
FROM (
SELECT 't1' AS t1, t1.* FROM t1
) t1 NATURAL FULL JOIN (
SELECT 't2' AS t2, t2.* FROM t2
) t2
WHERE NOT (t1, t2) IS NOT NULL;
复制代码
这将产生:
a |b |c |t1|t2|
--|--|--|--|--|
1| 2| 3|t1| |
10|11|12| |t2|
复制代码
为什么?因为NATURAL JOIN
is syntactic sugar for a join using all the shared column names of the two tables,而FULL JOIN
Make sure we can also retrieve columns that are not matched by the join predicate.另一种写法是:
-- Use JOIN .. USING, instead of NATURAL JOIN
SELECT *
FROM (
SELECT 't1' AS t1, t1.* FROM t1
) t1 FULL JOIN (
SELECT 't2' AS t2, t2.* FROM t2
) t2 USING (a, b, c)
WHERE NOT (t1, t2) IS NOT NULL;
复制代码
或者:
-- Use JOIN .. ON, instead of JOIN .. USING
SELECT
coalesce(t1.a, t2.a) AS a,
coalesce(t1.b, t2.b) AS b,
coalesce(t1.c, t2.c) AS c,
t1.t1,
t2.t2
FROM (
SELECT 't1' AS t1, t1.* FROM t1
) t1 FULL JOIN (
SELECT 't2' AS t2, t2.* FROM t2
) t2 ON (t1.a, t1.b, t1.c) = (t2.a, t2.b, t2.c)
WHERE NOT (t1, t2) IS NOT NULL;
复制代码
不幸的是,从PostgreSQL 12开始,This produces an error:
ERROR: FULL JOINOnly join conditions for mergeable joins or hashable joins are supported
优点和缺点
与使用UNION
和EXCEPT
compared to the set operator solution,优点和缺点:优点
- Each table is accessed only once
- Comparisons are now based on names,rather than column index based,也就是说,If only some of the columns are shared,它仍然可以工作.
缺点
- If index-based column comparison is required(因为表在结构上是相同的,But don't share the exact same column names),Then we have to rename each individual column to a common column name.
- 如果有重复的数据,There will be a Cartesian product,This can make this solution rather slow
UNION
和 ,将 的值视为 "非独立". 则不是这种情况.See workaround belowEXCEPT
NULL
NATURAL JOIN
当数据中存在NULL
值时
在有NULL
值的情况下,我们不能再使用NATURAL JOIN
或JOIN .. USING
.我们可以使用 [DISTINCT predicate](http://blog.jooq.org/2012/09/21/the-is-distinct-from-predicate/)
:
SELECT
coalesce(t1.a, t2.a) AS a,
coalesce(t1.b, t2.b) AS b,
coalesce(t1.c, t2.c) AS c,
t1.t1,
t2.t2
FROM (
SELECT 't1' AS t1, t1.* FROM t1
) t1 FULL JOIN (
SELECT 't2' AS t2, t2.* FROM t2
) t2 ON (t1.a, t1.b, t1.c) IS NOT DISTINCT FROM (t2.a, t2.b, t2.c)
WHERE NOT (t1, t2) IS NOT NULL;
复制代码
row value expressionNULL谓词
观察The esoteric expression of row valuesNULL
谓词的用法,It uses the truth table below:
+-----------------------+-----------+---------------+---------------+-------------------+
| Expression | R IS NULL | R IS NOT NULL | NOT R IS NULL | NOT R IS NOT NULL |
+-----------------------+-----------+---------------+---------------+-------------------+
| degree 1: null | true | false | false | true |
| degree 1: not null | false | true | true | false |
| degree > 1: all null | true | false | false | true |
| degree > 1: some null | false | false | true | true |
| degree > 1: none null | false | true | true | false |
+-----------------------+-----------+---------------+---------------+-------------------+
复制代码
是的.R IS NULL
和NOT R IS NOT NULL
在SQLis not the same thing...这只是另一种写法:
SELECT *
FROM (
SELECT 't1' AS t1, t1.* FROM t1
) t1 NATURAL FULL JOIN (
SELECT 't2' AS t2, t2.* FROM t2
) t2
WHERE t1 IS NULL
OR t2 IS NULL;
复制代码
边栏推荐
- hyperf的启动源码分析(二)——请求如何到达控制器
- Grab the tail of gold, silver and silver, unlock the programmer interview "Artifact of Brushing Questions"
- 20.nn.Module
- MySQL 23道经典面试吊打面试官
- ECCV2022: Recursion on Transformer without adding parameters and less computation!
- Selenium IDE for Selenium Automation Testing
- PHP Serialization: eval
- IDEA connects to MySQL database and uses data
- Node version switching management using NVM
- Sliding window method to segment data
猜你喜欢
拥塞控制,CDN,端到端
An article makes it clear!What is the difference and connection between database and data warehouse?
STM32的CAN过滤器
「面经分享」西北大学 | 字节 生活服务 | 一面二面三面 HR 面
MySQL has played to such a degree, no wonder the big manufacturers are rushing to ask for it!
C# using NumericUpDown control
Spark学习:为Spark Sql添加自定义优化规则
AWS实现定时任务-Lambda+EventBridge
endnote引用
C# using ComboBox control
随机推荐
ADS communicate with c #
golang-gin-优雅重启
Unity study notes Description of AVPro video jump function (Seeking)
拥塞控制,CDN,端到端
技能大赛训练题:MS15_034漏洞验证与安全加固
深度剖析 Apache EventMesh 云原生分布式事件驱动架构
leetcode:2032. Values that appear in at least two arrays
技能大赛训练题:登录安全加固
推荐系统-召回阶段-2013:DSSM(双塔模型)【Embedding(语义向量)召回】【微软】
numpy矩阵和向量的保存与加载,以及使用保存的向量进行相似度计算
golang-gin - graceful restart
Open Inventor 10.12 重大改进--和谐版
机器学习模型验证:被低估的重要一环
ECCV 2022 | Robotic Interaction Perception and Object Manipulation
go使用makefile脚本编译应用
Text similarity calculation (Chinese and English) detailed explanation of actual combat
为什么要分库分表?
3.爬虫之Scrapy框架1安装与使用
C# List Usage List Introduction
Save and load numpy matrices and vectors, and use the saved vectors for similarity calculation