自然连接和内部连接的区别

自然连接和内部连接有什么区别?

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.部分不在列名中;你只需要将column1column2column1column3作为标题)。

  • 一个内部连接就是要求返回第一个表中的一行的连接表中的匹配行
  • 一个外部联接是一个连接表中匹配的行不需要返回第一个表中的行的返回
  • 自然连接是假设连接条件是两个表中的同名列匹配的连接(可以有natural leftnatural 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 CORRESPONDINGEXCEPT 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 JOINCROSS 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”,并且一旦语法被解开,两者都表示相同的关系代数操作。 与OUTERLEFT / RIGHT )或CROSS连接的情况不同,它不是“不同的”连接。

请参阅Wikipedia上的equi-join部分:

自然连接提供了进一步的equi连接专业化。 连接谓词隐式地通过比较两个表中连接表中具有相同列名的所有列而隐含起来。 生成的连接表只包含每对同名列的一列。

大多数专家认为NATURAL JOINs是危险的,因此强烈阻止它们的使用。 危险来自无意中添加一个新的列,命名为相同的另一列…

也就是说, 所有NATURAL连接都可以写成INNER连接 (但反过来不是这样)。 为此,只需明确地创build谓词 – 例如USINGON – 并且如Jonathan Leffler所指出的那样,如果需要的话,select期望的结果集列以避免“重复”。

快乐的编码。


NATURAL关键字也可以应用于LEFTRIGHT连接,同样适用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)