自然连接和内连接有什么区别?
答案 0 :(得分:216)
INNER JOIN和NATURAL JOIN之间的一个显着区别是返回的列数。
考虑:
TableA TableB
+------------+----------+ +--------------------+
|Column1 | Column2 | |Column1 | Column3 |
+-----------------------+ +--------------------+
| 1 | 2 | | 1 | 3 |
+------------+----------+ +---------+----------+
Table1的INNER JOIN
和Column1上的TableB将返回
SELECT * FROM TableA INNER JOIN TableB USING (Column1);
SELECT * FROM TableA INNER JOIN TableB ON TableA.Column1 = TableB.Column1;
+------------+-----------+---------------------+
| a.Column1 | a.Column2 | b.Column1| b.Column3|
+------------------------+---------------------+
| 1 | 2 | 1 | 3 |
+------------+-----------+----------+----------+
Column1上的NATURAL JOIN
和Column1上的TableB将返回:
SELECT * FROM TableA NATURAL JOIN TableB
+------------+----------+----------+
|Column1 | Column2 | Column3 |
+-----------------------+----------+
| 1 | 2 | 3 |
+------------+----------+----------+
避免重复列。
(来自标准语法的AFAICT,您不能在自然连接中指定连接列;连接严格基于名称。另请参阅Wikipedia。)
(内联接输出中有作弊; a.
和b.
部分不在列名中;您只有column1
,{{ 1}},column2
,column1
作为标题。)
答案 1 :(得分:78)
natural left
或natural right
),它假定连接条件与两个表中的同名列匹配< / LI>
我会避免使用像瘟疫这样的自然连接,因为天然连接是:
答案 2 :(得分:22)
自然连接只是避免输入的捷径,假设连接很简单并且匹配同名字段。
SELECT
*
FROM
table1
NATURAL JOIN
table2
-- implicitly uses `room_number` to join
与......相同。
SELECT
*
FROM
table1
INNER JOIN
table2
ON table1.room_number = table2.room_number
然而,使用快捷方式格式无法做的是更复杂的连接......
SELECT
*
FROM
table1
INNER JOIN
table2
ON (table1.room_number = table2.room_number)
OR (table1.room_number IS NULL AND table2.room_number IS NULL)
答案 3 :(得分:12)
SQL在很多方面都不忠实于关系模型。 SQL查询的结果不是关系,因为它可能具有重复名称,“匿名”(未命名)列,重复行,空值等的列.SQL不会将表视为关系,因为它依赖于列排序等。
SQL中NATURAL JOIN
背后的想法是让它更容易更忠实于关系模型。两个表的NATURAL JOIN
的结果将按名称重复列,因此没有匿名列。同样,提供UNION CORRESPONDING
和EXCEPT CORRESPONDING
来解决SQL在遗留UNION
语法中对列排序的依赖。
然而,与所有编程技术一样,它需要纪律才有用。成功NATURAL JOIN
的一个要求始终是命名列,因为连接隐含在具有相同名称的列上(遗憾的是,在SQL中重命名列的语法是冗长的,但副作用是在命名时鼓励纪律基表中的列和VIEW
s :)
注意SQL NATURAL JOIN
是一个等同连接**,但这不是有用的障碍。考虑如果NATURAL JOIN
是SQL中唯一支持的连接类型,它仍然是relationally complete。
虽然确实可以使用NATURAL JOIN
和投影(INNER JOIN
)编写任何SELECT
,但任何INNER JOIN
都可以使用产品编写(CROSS JOIN
)和限制(WHERE
);进一步注意,没有共同列名的表之间的NATURAL JOIN
将得到与CROSS JOIN
相同的结果。所以,如果你只对关系结果感兴趣(为什么不关注?!)那么NATURAL JOIN
是你需要的唯一连接类型。当然,从语言设计的角度来看,INNER JOIN
和CROSS JOIN
之类的短序有其价值,但也认为几乎所有SQL查询都可以用10种语法不同的方式编写,但在语义上等同于方式这就是使SQL优化器难以开发的原因。
以下是一些在语义上等效的示例查询(使用the usual parts and suppliers database):
SELECT *
FROM S NATURAL JOIN SP;
-- Must disambiguate and 'project away' duplicate SNO attribute
SELECT S.SNO, SNAME, STATUS, CITY, PNO, QTY
FROM S INNER JOIN SP
USING (SNO);
-- Alternative projection
SELECT S.*, PNO, QTY
FROM S INNER JOIN SP
ON S.SNO = SP.SNO;
-- Same columns, different order == equivalent?!
SELECT SP.*, S.SNAME, S.STATUS, S.CITY
FROM S INNER JOIN SP
ON S.SNO = SP.SNO;
-- 'Old school'
SELECT S.*, PNO, QTY
FROM S, SP
WHERE S.SNO = SP.SNO;
**关系自然连接不是等值连接,它是一个投影。 - philipxy
答案 4 :(得分:8)
NATURAL
联接只是特定 INNER
联接 - 或“equi-join”的简短语法 - 并且,一旦语法被解包,两者都代表相同的关系代数运算。与OUTER
(LEFT
/ RIGHT
)或CROSS
联接的情况一样,这不是加入的“不同类型”。
请参阅维基百科上的equi-join部分:
自然连接提供了equi-joins的进一步专业化。 通过比较连接表中具有相同列名的两个表中的所有列,隐式地产生连接谓词。生成的连接表仅包含每对的一列同名的专栏。
大多数专家同意天然连接是危险的,因此强烈反对使用它们。危险来自于无意中添加了一个新列,命名与另一列相同......
也就是说,所有NATURAL
个连接都可以写成INNER
连接(但反之则不然)。为此,只需创建谓词显式 - 例如USING
或ON
- 并且正如Jonathan Leffler所指出的那样,选择所需的结果集列以避免“重复”(如果需要)。
快乐的编码。
(NATURAL
关键字也可以应用于LEFT
和RIGHT
联接,同样适用。NATURAL LEFT/RIGHT
联接只是具体 LEFT/RIGHT
加入。)
答案 5 :(得分:2)
自然连接:它是两个表中所有列的组合或组合结果。 它将返回第一个表相对于第二个表的所有行。
内部联接:除非任何列名在两个表中是sxame,否则此联接将起作用
答案 6 :(得分:0)
自然连接是在所有公共列的基础上连接2个表的地方。
common column:是两个表中具有相同名称的列+在两个表中都具有兼容的数据类型。 您只能使用=运算符
内部连接是根据ON子句中提到的公共列连接2个表的地方。
common column:是一个列,在两个表中都具有兼容的数据类型,但不需要具有相同的名称。
您只能使用任何比较运算符,例如=
,<=
,>=
,<
,>
,<>
答案 7 :(得分:-2)
不同之处在于int内部(equi / default)连接和natuarl连接公共列win中的自然连接将在单次显示但内部/ equi / default / simple连接公共列将显示双倍时间。
答案 8 :(得分:-2)
内部连接和自然连接几乎相同,但它们之间存在细微差别。不同之处在于自然连接不需要指定条件,但在内连接条件下是强制性的。如果我们在内连接中指定条件,则结果表就像笛卡尔积。
答案 9 :(得分:-3)
mysql> SELECT * FROM tb1 ;
+----+------+
| id | num |
+----+------+
| 6 | 60 |
| 7 | 70 |
| 8 | 80 |
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+------+
6 rows in set (0.00 sec)
mysql> SELECT * FROM tb2 ;
+----+------+
| id | num |
+----+------+
| 4 | 40 |
| 5 | 50 |
| 9 | 90 |
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+------+
6 rows in set (0.00 sec)
INNER JOIN:
mysql> SELECT * FROM tb1 JOIN tb2 ;
+----+------+----+------+
| id | num | id | num |
+----+------+----+------+
| 6 | 60 | 4 | 40 |
| 7 | 70 | 4 | 40 |
| 8 | 80 | 4 | 40 |
| 1 | 1 | 4 | 40 |
| 2 | 2 | 4 | 40 |
| 3 | 3 | 4 | 40 |
| 6 | 60 | 5 | 50 |
| 7 | 70 | 5 | 50 |
| 8 | 80 | 5 | 50 |
.......more......
return 36 rows in set (0.01 sec)
AND NATURAL JOIN :
mysql> SELECT * FROM tb1 NATURAL JOIN tb2 ;
+----+------+
| id | num |
+----+------+
| 1 | 1 |
| 2 | 2 |
| 3 | 3 |
+----+------+
3 rows in set (0.01 sec)
答案 10 :(得分:-4)
内连接,连接两个列名相同的表。
自然连接,连接两个表,列名和数据类型相同。