SQL中各种连接的区别

时间:2015-06-23 03:21:59

标签: mysql join

我对natural jointheta joininner join感到困惑,因为他们都倾向于为下面给出的模式提供相同的结果。

按定义:

  

自然连接形成其两个参数的笛卡尔积,对两个关系模式中出现的属性执行强制相等的选择。

     

theta join是自然连接操作的扩展,允许我们在单个操作中组合选择和笛卡尔积

     

内连接使用给定的连接条件计算两个关系的theta连接。

考虑架构:

mysql> select * from loan;
+---------+-------------+--------+
| loan_id | branch_name | amount |
+---------+-------------+--------+
| L11     | Round Hill  |    900 |
| L14     | Downtown    |   1500 |
| L15     | Perryridge  |   1500 |
| L16     | Perryridge  |   1300 |
| L17     | Downtown    |   1000 |
| L23     | Redwood     |   2000 |
| L93     | Mianus      |    500 |
+---------+-------------+--------+
7 rows in set (0.00 sec)

mysql> select * from borrower;
+---------------+---------+
| customer_name | loan_id |
+---------------+---------+
| Adams         | L16     |
| Curry         | L93     |
| Hayes         | L15     |
| Jackson       | L14     |
| Jones         | L17     |
| Smith         | L11     |
| Smith         | L23     |
| Williams      | L17     |
| Adams         | L19     |
| Adams         | L15     |
| Jones         | L15     |
| Williams      | L23     |
+---------------+---------+
12 rows in set (0.00 sec)

Natual Join

mysql> select * from loan l, borrower b where l.loan_id=b.loan_id;
+---------+-------------+--------+---------------+---------+
| loan_id | branch_name | amount | customer_name | loan_id |
+---------+-------------+--------+---------------+---------+
| L16     | Perryridge  |   1300 | Adams         | L16     |
| L93     | Mianus      |    500 | Curry         | L93     |
| L15     | Perryridge  |   1500 | Hayes         | L15     |
| L14     | Downtown    |   1500 | Jackson       | L14     |
| L17     | Downtown    |   1000 | Jones         | L17     |
| L11     | Round Hill  |    900 | Smith         | L11     |
| L23     | Redwood     |   2000 | Smith         | L23     |
| L17     | Downtown    |   1000 | Williams      | L17     |
| L15     | Perryridge  |   1500 | Adams         | L15     |
| L15     | Perryridge  |   1500 | Jones         | L15     |
| L23     | Redwood     |   2000 | Williams      | L23     |
+---------+-------------+--------+---------------+---------+
11 rows in set (0.01 sec)

Theta Join

mysql> select * from loan l join borrower b on l.loan_id=b.loan_id;
+---------+-------------+--------+---------------+---------+
| loan_id | branch_name | amount | customer_name | loan_id |
+---------+-------------+--------+---------------+---------+
| L16     | Perryridge  |   1300 | Adams         | L16     |
| L93     | Mianus      |    500 | Curry         | L93     |
| L15     | Perryridge  |   1500 | Hayes         | L15     |
| L14     | Downtown    |   1500 | Jackson       | L14     |
| L17     | Downtown    |   1000 | Jones         | L17     |
| L11     | Round Hill  |    900 | Smith         | L11     |
| L23     | Redwood     |   2000 | Smith         | L23     |
| L17     | Downtown    |   1000 | Williams      | L17     |
| L15     | Perryridge  |   1500 | Adams         | L15     |
| L15     | Perryridge  |   1500 | Jones         | L15     |
| L23     | Redwood     |   2000 | Williams      | L23     |
+---------+-------------+--------+---------------+---------+
11 rows in set (0.00 sec)

内部加入

mysql> select * from loan l inner join borrower b on l.loan_id=b.loan_id;
+---------+-------------+--------+---------------+---------+
| loan_id | branch_name | amount | customer_name | loan_id |
+---------+-------------+--------+---------------+---------+
| L16     | Perryridge  |   1300 | Adams         | L16     |
| L93     | Mianus      |    500 | Curry         | L93     |
| L15     | Perryridge  |   1500 | Hayes         | L15     |
| L14     | Downtown    |   1500 | Jackson       | L14     |
| L17     | Downtown    |   1000 | Jones         | L17     |
| L11     | Round Hill  |    900 | Smith         | L11     |
| L23     | Redwood     |   2000 | Smith         | L23     |
| L17     | Downtown    |   1000 | Williams      | L17     |
| L15     | Perryridge  |   1500 | Adams         | L15     |
| L15     | Perryridge  |   1500 | Jones         | L15     |
| L23     | Redwood     |   2000 | Williams      | L23     |
+---------+-------------+--------+---------------+---------+
11 rows in set (0.01 sec)

所有查询都返回相同的结果。他们之间有什么区别?

3 个答案:

答案 0 :(得分:2)

https://en.wikipedia.org/wiki/Relational_algebra

提供您尝试理解的不同联接的最佳解释。

自然连接是两组之间最基本的连接类型。比较两个元组中元组的主键和相应外键的相等性,以得出连接的元组集。

用户@amalamalpm指出:

  

theta join允许任意比较关系。

因为theta连接允许任意比较,所以可以将自然连接视为theta连接的子集。

内连接是theta连接的sql实现,因此无论何时使用自然连接都会使用。

注意:在mysql中,您可以执行以下操作以获得自然连接。这需要更少的角色,并且被懒惰的人(像我一样)所青睐。

select * from loan natural join borrower

这也将删除两个集合中存在的重复字段loan_id(即仅在结果集中显示一次)。

您编写查询的三种方法都是尝试获得相同的结果集。

您正在进行自然加入>>这是theta join的一个子集>>这是sql用语中的内连接。

所以mysql给你相同的结果集。 我没有对它们运行explain extended所以我不能保证这个,但是我猜想mysql也会执行相同的查询。

答案 1 :(得分:1)

  • 在自然加入中,加入属性的名称和域必须相同。

  • 在内连接中,只有连接属性的域需要相同

  • theta连接允许任意比较关系(例如 ≥)。

答案 2 :(得分:0)

在MySQL中,所有这三个查询都是相同的。

  select * from loan l, borrower b where l.loan_id=b.loan_id;

  select * from loan l join borrower b on l.loan_id=b.loan_id;

  select * from loan l inner join borrower b on l.loan_id=b.loan_id;

在实践中,每个查询都是 equi-joins

“从理论上讲,理论与实践之间没有区别。在实践中,有”

应用诸如“自然”,“theta”和“内在”等理论标签并不会改变所有这三个陈述相同的事实。所有这三个陈述都是一样的。

第一个语句只是使用旧式逗号语法进行连接操作。第一个语句中的逗号等同于JOIN关键字。

在MySQL INNER JOIN中与JOIN同义。也就是说,添加或删除关键字INNER没有任何影响。

谓词是谓词是谓词。返回的行必须满足条件,条件是在ON子句还是WHERE子句中指定(在内连接的情况下)并不重要。