当前位置:网站首页>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 belowEXCEPTNULLNATURAL 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;
复制代码边栏推荐
猜你喜欢

pytorch gpu版本安装最新

Miller_Rabin 米勒拉宾概率筛【模板】

Install the latest pytorch gpu version

尚硅谷-JVM-内存和垃圾回收篇(P1~P203)

3.爬虫之Scrapy框架1安装与使用

C# using ComboBox control

Analysis of the startup source code of hyperf (2) - how the request reaches the controller

Detailed explanation of network protocols and related technologies

Resnet&API

拥塞控制,CDN,端到端
随机推荐
为什么 wireguard-go 高尚而 boringtun 孬种
Shell项目实战1.系统性能分析
ML、DL、CV常见的问题整理
Selenium IDE for Selenium Automation Testing
LeetCode·304竞赛·6132·使数组中所有元素都等于零·模拟·哈希
1-hour live broadcast recruitment order: industry leaders share dry goods, and enterprise registration is open丨qubit · point of view
ERROR: Failed building wheel for osgeo
CodeIgniter 打开错误日志
代码随想录笔记_哈希_454四数相加II
Motion capture system for end-positioning control of flexible manipulators
232层3D闪存芯片来了:单片容量2TB,传输速度提高50%
使用CompletableFuture进行异步处理业务
一篇文章讲清楚!数据库和数据仓库到底有什么区别和联系?
Linux bash: redis-server: command not found
五个维度着手MySQL的优化
C# control StatusStrip use
ECCV2022: Recursion on Transformer without adding parameters and less computation!
Linux bash: redis-server: 未找到命令
动作捕捉系统用于柔性机械臂的末端定位控制
[Blue Bridge Cup Trial Question 46] Scratch Magnet Game Children's Programming Scratch Blue Bridge Cup Trial Question Explanation