自然连接和内部连接的区别
自然连接和内部连接有什么区别?
INNER JOIN和NATURAL JOIN之间的一个显着区别是返回的列数。
考虑:
TableA TableB Column1 Column2 Column1 Column3 1 2 1 3
Column1的TableA和TableB的INNER JOIN将返回
a.column1 a.column2 b.column1 b.column3 1 2 1 3 SELECT * FROM TableA INNER JOIN TableB USING (Column1) SELECT * FROM TableA INNER JOIN TableB ON TableA.Column1 = TableB.Column1
Column1的TableA和TableB的NATURAL JOIN将返回:
column1 column2 column3 1 2 3 SELECT * FROM TableA NATURAL JOIN TableB
避免重复列。
(来自标准语法的AFAICT,你不能在自然连接中指定连接列;连接是严格基于名称的,参见维基百科) 。
( 内连接输出中有一个作弊; a.
和b.
部分不在列名中;你只需要将column1
, column2
, column1
, column3
作为标题)。
- 一个内部连接就是要求返回第一个表中的一行的连接表中的匹配行
- 一个外部联接是一个连接表中匹配的行不需要返回第一个表中的行的返回
- 自然连接是假设连接条件是两个表中的同名列匹配的连接(可以有
natural left
或natural right
)
我会避免像瘟疫一样使用自然连接,因为自然连接是:
- 不是标准的SQL,因此不是可移植的,不可读(大多数SQL编码器),并且可能不被各种工具/库支持
- 没有信息; 如果不参考模式,您无法确定要join哪些列
- 您的连接条件对架构更改是不可见的 – 如果存在多个自然连接列,并且从表中删除了一个这样的列,则查询仍然会执行,但可能不正确,并且此行为中的更改将保持沉默
- 几乎没有值得的努力; 你只能节省大约10秒的打字时间
自然连接只是避免打字的一个捷径,假定连接简单并匹配相同名称的字段。
SELECT * FROM table1 NATURAL JOIN table2 USING (room_number)
是相同的…
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)
SQL在很多方面都不忠于关系模型。 SQL查询的结果不是一个关系,因为它可能具有重复名称,“匿名”(未命名)列,重复行,空值等列.SQL不将表视为关系,因为它依赖于列sorting等。
SQL中的NATURAL JOIN
背后的思想是让关系模型变得更加忠实。 两个表的NATURAL JOIN
的结果将会有名称重复的列,因此不会有匿名列。 同样,提供了UNION CORRESPONDING
和EXCEPT CORRESPONDING
来解决SQL在传统UNION
语法中对列sorting的依赖。
但是,像所有的编程技术一样,它需要纪律才能有用。 一个成功NATURAL JOIN
要求是一致命名的列,因为连接隐含在具有相同名称的列上(很遗憾,在SQL中重命名列的语法是冗长的,但副作用是鼓励在基础中命名列表和VIEW
🙂
注意一个NATURAL JOIN
是一个equi-join,但这不是有用的障碍。 考虑一下,如果NATURAL JOIN
是SQL中唯一支持的连接types,它仍然是关系完整的 。
虽然确实可以使用INNER JOIN
和projection( SELECT
)来编写NATURAL JOIN
,但也可以使用product( CROSS JOIN
)和restriction( WHERE
)来写入INNER JOIN
。 进一步注意,没有列名称的表之间的NATURAL JOIN
将给出与CROSS JOIN
相同的结果。 所以如果你只关心结果是关系(为什么不呢?),那么NATURAL JOIN
是唯一你需要的连接types。 当然,从语言devise的angular度来看, 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' style SELECT * FROM S, SP WHERE S.SNO = SP.SNO;
NATURAL
连接只是特定 INNER
连接的简短语法 – 或“equi-join”,并且一旦语法被解开,两者都表示相同的关系代数操作。 与OUTER
( LEFT
/ RIGHT
)或CROSS
连接的情况不同,它不是“不同的”连接。
请参阅Wikipedia上的equi-join部分:
自然连接提供了进一步的equi连接专业化。 连接谓词隐式地通过比较两个表中连接表中具有相同列名的所有列而隐含起来。 生成的连接表只包含每对同名列的一列。
大多数专家认为NATURAL JOINs是危险的,因此强烈阻止它们的使用。 危险来自无意中添加一个新的列,命名为相同的另一列…
也就是说, 所有NATURAL
连接都可以写成INNER
连接 (但反过来不是这样)。 为此,只需明确地创build谓词 – 例如USING
或ON
– 并且如Jonathan Leffler所指出的那样,如果需要的话,select期望的结果集列以避免“重复”。
快乐的编码。
( NATURAL
关键字也可以应用于LEFT
和RIGHT
连接,同样适用NATURAL LEFT/RIGHT
连接只是特定 LEFT/RIGHT
连接的简短语法。
自然连接:它是两个表中所有列的组合或组合结果。 它将返回第一个表的所有行相对于第二个表。
内部连接:除非列名中的任何一个在两个表中都是sxame,否则这个连接将起作用
内连接和自然连接几乎相同,但是它们之间有细微的差别。 不同之处在于自然连接不需要指定条件,但内部连接条件是强制性的。 如果我们在内部连接中指定条件,那么结果表就像笛卡尔积。
自然连接是在所有公共列的基础上连接2个表的地方。
公共列:是两个表中具有相同名称的列+两个表中都具有兼容的数据types。 您只能使用=运算符
内部连接是在ON子句中提到的公共列的基础上连接2个表的地方。
公共列:是在两个表中具有兼容数据types的列,但不必具有相同的名称。 您只能使用任何比较运算符,如=
, <=
, >=
, <
, >
, <>
不同之处在于int(inner)/ equine(自动/默认)连接和天然连接在天然连接共同列中将单独显示,而inner / equi / default / simple连接共同列将显示双倍时间。
内连接,连接两个列名相同的表。
自然连接,连接两个表的列名和数据types相同。
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)