自然连接和内部连接之间的区别是什么?


当前回答

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)

其他回答

INNER JOIN和NATURAL JOIN之间的一个显著区别是返回的列数。

考虑:

TableA                           TableB
+------------+----------+        +--------------------+    
|Column1     | Column2  |        |Column1  |  Column3 |
+-----------------------+        +--------------------+
| 1          |  2       |        | 1       |   3      |
+------------+----------+        +---------+----------+

TableA和TableB在Column1上的INNER JOIN将返回

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      |
+------------+-----------+----------+----------+

TableA和TableB在Column1上的NATURAL JOIN将返回:

SELECT * FROM TableA NATURAL JOIN TableB
+------------+----------+----------+    
|Column1     | Column2  | Column3  |
+-----------------------+----------+
| 1          |  2       |   3      |
+------------+----------+----------+

避免了重复列。

(AFAICT从标准语法来看,您不能在自然连接中指定连接列;连接严格基于名称。参见维基百科。)

(在内部连接输出中有一个欺骗;a和b部分不会在列名中;你只需要用columnn1, column2, columnn1, column3作为标题。)

自然连接是在所有公共列的基础上连接两个表。

Common列:在两个表中具有相同名称的列,并且在两个表中具有兼容的数据类型。 只能使用=运算符

内部连接是在on子句中提到的公共列的基础上连接两个表。

公共列:在两个表中都具有兼容数据类型的列,但不需要具有相同的名称。 您只能使用任何比较运算符,例如=,<=,>=,<,>,<>

不同的是,内部(equi/default)连接和自然连接,自然连接公共列中的win将在单次显示,但内部/equi/default/简单连接公共列将显示两次。

内连接和自然连接基本相同,但有细微的区别。不同的是,在自然连接中不需要指定条件,但在内部连接中条件是必须的。如果我们在内连接中指定条件,则生成的表就像笛卡尔积。

SQL在很多方面并不忠实于关系模型。SQL查询的结果不是一个关系,因为它可能有重复名称的列、“匿名”(未命名)列、重复行、空值等。SQL不将表视为关系,因为它依赖于列排序等。

SQL中NATURAL JOIN背后的思想是更容易更忠实于关系模型。两个表的NATURAL JOIN的结果将有按名称重复的列,因此没有匿名列。类似地,提供了UNION对应和EXCEPT对应,以解决SQL在遗留UNION语法中对列排序的依赖。

然而,与所有编程技术一样,它需要纪律才能发挥作用。成功的NATURAL JOIN的一个要求是一致地命名列,因为连接隐含在具有相同名称的列上(遗憾的是,SQL中重命名列的语法很冗长,但副作用是鼓励在基本表和视图中命名列时遵守纪律:)

注意,SQL NATURAL JOIN是等价连接**,但这并不妨碍它的有用性。如果NATURAL JOIN是SQL中唯一支持的连接类型,那么它仍然是关系完整的。

While it is indeed true that any NATURAL JOIN may be written using INNER JOIN and projection (SELECT), it is also true that any INNER JOIN may be written using product (CROSS JOIN) and restriction (WHERE); further note that a NATURAL JOIN between tables with no column names in common will give the same result as CROSS JOIN. So if you are only interested in results that are relations (and why ever not?!) then NATURAL JOIN is the only join type you need. Sure, it is true that from a language design perspective shorthands such as INNER JOIN and CROSS JOIN have their value, but also consider that almost any SQL query can be written in 10 syntactically different, but semantically equivalent, ways and this is what makes SQL optimizers so very hard to develop.

下面是一些语义等价的查询示例(使用常用的零件和供应商数据库):

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