Answers:
INNER JOIN和NATURAL JOIN之间的一个重要区别是返回的列数。
考虑:
TableA TableB
+------------+----------+ +--------------------+
|Column1 | Column2 | |Column1 | Column3 |
+-----------------------+ +--------------------+
| 1 | 2 | | 1 | 3 |
+------------+----------+ +---------+----------+
在INNER JOIN
表A和表B对列1将返回
SELECT * FROM TableA AS a INNER JOIN TableB AS b USING (Column1);
SELECT * FROM TableA AS a INNER JOIN TableB AS b ON a.Column1 = b.Column1;
+------------+-----------+---------------------+
| a.Column1 | a.Column2 | b.Column1| b.Column3|
+------------------------+---------------------+
| 1 | 2 | 1 | 3 |
+------------+-----------+----------+----------+
在NATURAL JOIN
表A和表B在列1将返回:
SELECT * FROM TableA NATURAL JOIN TableB
+------------+----------+----------+
|Column1 | Column2 | Column3 |
+-----------------------+----------+
| 1 | 2 | 3 |
+------------+----------+----------+
避免重复的列。
(根据标准语法的AFAICT,您不能在自然连接中指定连接列;该连接严格基于名称。另请参见Wikipedia。)
(有一个在内部备忘加入输出;在a.
与b.
部分将不会在列名,你只是有column1
,column2
,column1
,column3
作为标题。)
NATURAL JOIN
将毁灭,为什么会出乎意料以及您所处的世界吗?
Customers
与之间自然相连Employees
,然后继续EmployeeID
。 Employees
也有一个ManagerID
领域。一切安好。然后,有一天,有人将一个ManagerID
字段添加到Customers
表中。您的加入不会中断(这将是一个怜悯),相反,它现在将包括第二个字段,并且工作不正确。因此,看似无害的变化可能会破坏远距离相关的事物。很坏。自然连接的唯一好处是节省了一些键入操作,而且缺点很大。
SELECT * FROM TableA INNER JOIN TableB USING (Column1)
4栏。这是不正确的,因为SELECT * FROM TableA INNER JOIN TableB USING (Column1)
和SELECT * FROM TableA NATURAL JOIN TableB
相等,它们都给出3列。
natural left
或natural right
),它假定连接标准是其中两个表匹配的同名列我会避免使用像瘟疫这样的自然联接,因为自然联接是:
NATURAL JOIN Checkouts
只有在正式且强制执行数据库命名约定时,才可能使用看起来随意的” Books “。”
id
它无处不在且无用。通常的外键名称是tablename_id
。自然连接是一个坏,坏,坏的主意。
自然联接只是避免键入的捷径,前提是联接很简单并且匹配具有相同名称的字段。
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)
NATURAL JOIN ... USING ()
?该标准是任一a NATURAL JOIN b
或a JOIN b USING (c)
room_number
联接的查询结果将只有一个名为的列,而内部联接将有两个名为的列room_number
。
SQL在许多方面都不忠实于关系模型。SQL查询的结果不是关系,因为它可能具有名称重复的列,“匿名”(未命名)列,重复的行,空值等。SQL不会将表视为关系,因为它依赖于列顺序等。
NATURAL JOIN
SQL 背后的思想是使对关系模型的忠诚更容易。NATURAL JOIN
两个表的结果将具有按名称重复删除的列,因此没有匿名列。类似地,提供了UNION CORRESPONDING
和EXCEPT CORRESPONDING
来解决旧版中SQL对列顺序的依赖。UNION
语法。
但是,与所有编程技术一样,它要求纪律有用。成功的一个要求NATURAL JOIN
是命名字段的名称始终一致,因为联接隐含在具有相同名称的列上(在SQL中重命名列的语法很冗长,但是副作用是鼓励在基表和列中命名列时的纪律性。VIEW
s :)
请注意,SQL NATURAL JOIN
是等值连接**,但是这并不意味着实用性。考虑一下,如果这NATURAL JOIN
是SQL支持的唯一连接类型,则它仍然是关系完整的。
确实NATURAL JOIN
可以使用INNER JOIN
和投影(SELECT
)编写任何内容,但也INNER JOIN
可以使用乘积(CROSS JOIN
)和限制(WHERE
)编写任何内容;进一步注意,NATURAL JOIN
没有共同列名的表之间的a 将产生与相同的结果CROSS JOIN
。因此,如果您仅对作为关系的结果感兴趣(为什么不这样做?!),那么这NATURAL JOIN
是您唯一需要的联接类型。当然,这是事实,从语言设计的角度来看的速记如INNER JOIN
和CROSS JOIN
具有它们的价值,但同时也考虑到几乎所有SQL查询都可以用10种语法上不同但在语义上等效的方式来编写,这使SQL优化器非常困难。发展。
以下是一些语义上等效的示例查询(使用普通零件和供应商数据库):
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;
**关系自然连接不是等连接,而是一个连接的投影。–费城
一个NATURAL
连接是一个只是短期的语法具体 INNER
加盟-或“相等连接” -而且,一旦语法是解开,既代表相同的关系代数操作。与OUTER
(LEFT
/ RIGHT
)或CROSS
join 的情况不同,它不是“不同的” 联接。
请参阅Wikipedia上的等参部分:
自然联接提供了对等联接的进一步专业化。通过比较两个表中所有在联接表中具有相同列名的列,可以隐式地产生联接谓词。对于每对同名列,结果联接表仅包含一个列。
大多数专家都认为,NATURAL JOIN非常危险,因此强烈建议不要使用它们。危险来自无意中添加了与另一列相同名称的新列...
也就是说,所有NATURAL
联接都可以写为INNER
联接(但反之则不成立)。为此,只需显式创建谓词 -例如,USING
或ON
,并且正如Jonathan Leffler所指出的那样,选择所需的结果集列,以在需要时避免“重复”。
快乐的编码。
(NATURAL
关键字也可以应用于LEFT
和RIGHT
联接,同样也适用。联接NATURAL LEFT/RIGHT
只是特定 联接的简短语法LEFT/RIGHT
。)
自然联接是在所有公共列的基础上联接2个表的地方。
common column:是在两个表中具有相同名称的列,并且在两个表中具有兼容的数据类型。您只能使用=运算符
内部联接是在ON子句中提到的公用列的基础上联接2个表的地方。
common column:是在两个表中具有兼容数据类型但不必具有相同名称的列。你可以只使用任何运营商比较像=
,<=
,>=
,<
,>
,<>
区别在于int内部(equi / default)连接和自然连接在natuarl连接公共列win中将一次显示,而inner / equi / default / simple连接公共列将显示两次。
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)
内部联接 :
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)