当前位置:网站首页>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;
复制代码
边栏推荐
- 以后面试官问你 为啥不建议使用Select *,请你大声回答他!
- Motion capture system for end-positioning control of flexible manipulators
- Unity study notes Description of AVPro video jump function (Seeking)
- ERROR: Failed building wheel for osgeo
- STM32的CAN过滤器
- The operator,
- 百度网盘安装在c盘显示系统权限限制的解决方法
- How IDEA runs web programs
- 技能大赛训练题:ftp 服务攻防与加固
- Shell项目实战1.系统性能分析
猜你喜欢
Reasons and solutions for Invalid bound statement (not found)
MySQL has played to such a degree, no wonder the big manufacturers are rushing to ask for it!
新款现代帕里斯帝预售开启,安全、舒适一个不落
Motion capture system for end-positioning control of flexible manipulators
C# Get network card information NetworkInterface IPInterfaceProperties
Error IDEA Terminated with exit code 1
ICML2022 | Fully Granular Self-Semantic Propagation for Self-Supervised Graph Representation Learning
3.爬虫之Scrapy框架1安装与使用
MySQL【子查询】
Miller_Rabin 米勒拉宾概率筛【模板】
随机推荐
Shell script classic case: detecting whether a batch of hosts is alive
技能大赛dhcp服务训练题
Redis 】 【 publish and subscribe message
numpy矩阵和向量的保存与加载,以及使用保存的向量进行相似度计算
C# control ToolStripProgressBar usage
csdn发文助手问题
C# control StatusStrip use
What should I do if selenium is reversed?
Buffer 与 拥塞控制
一篇文章讲清楚!数据库和数据仓库到底有什么区别和联系?
Miller_Rabin 米勒拉宾概率筛【模板】
LeetCode·每日一题·1161.最大层内元素和·层次遍历
CLion用于STM32开发
龟速乘【模板】
PHP Serialization: eval
五个维度着手MySQL的优化
Node version switching management using NVM
4.爬虫之Scrapy框架2数据解析&配置参数&数据持久化&提高Scrapy效率
Open Inventor 10.12 重大改进--和谐版
Open Inventor 10.12 Major Improvements - Harmony Edition