当前位置:网站首页>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;
复制代码
边栏推荐
猜你喜欢
IDEA can't find the Database solution
C# Get network card information NetworkInterface IPInterfaceProperties
Install the latest pytorch gpu version
Redis 】 【 publish and subscribe message
尚硅谷-JVM-内存和垃圾回收篇(P1~P203)
Comparison of Optical Motion Capture and UWB Positioning Technology in Multi-agent Cooperative Control Research
C# control ListView usage
AWS实现定时任务-Lambda+EventBridge
AWS implements scheduled tasks - Lambda+EventBridge
3.爬虫之Scrapy框架1安装与使用
随机推荐
技能大赛训练题:交换机虚拟化练习
Resolved (pymysqL connect to the database error) pymysqL. Err. ProgrammingError: (1146, "Table" test. Students' doesn 't exist ")
龟速乘【模板】
新款现代帕里斯帝预售开启,安全、舒适一个不落
Selenium IDE for Selenium Automation Testing
C# Get network card information NetworkInterface IPInterfaceProperties
The batch size does not have to be a power of 2!The latest conclusions of senior ML scholars
IDEA can't find the Database solution
【redis】发布和订阅消息
golang-gin - graceful restart
C# control StatusStrip use
【Pytorch】F.softmax()方法说明
49.【拷贝构造函数与重载】
hyperf的启动源码分析(二)——请求如何到达控制器
Error IDEA Terminated with exit code 1
Even if the image is missing in a large area, it can also be repaired realistically. The new model CM-GAN takes into account the global structure and texture details
Resnet&API
The latest complete code: Incremental training using the word2vec pre-training model (two loading methods corresponding to two saving methods) applicable to various versions of gensim
Linux bash: redis-server: command not found
尚硅谷-JVM-内存和垃圾回收篇(P1~P203)