mysql - SQL中各种join的区别

标签 mysql join

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

根据定义:

The natural join forms a Cartesian product of its two arguments, performs a selection forcing equality on those attributes that appear in both relation schema.

The theta join is an extension to the natural join operation that allows us to combine a selection and Cartesian product in a single operation

The inner join computes the theta join of the two relations with the given join condition.

考虑模式:

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)

自然连接

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 连接

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)

所有查询返回相同的结果。它们有什么区别?

最佳答案

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

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

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

正如用户@amalamalpm 指出的那样:

a theta join allows for arbitrary comparison relationships.

因为 theta 连接允许任意比较,自然连接可以被认为是 theta 连接的一个子集。

内连接是 theta 连接的 sql 实现,因此在使用自然连接时使用。

注意:在mysql中,您可以执行以下操作以获得自然连接。这需要更少的字符,并且受到懒惰的人(比如我)的青睐。

select * from loan natural join borrower

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

您编写查询的三种方式都试图获得相同的结果集。

您正在执行自然连接 >>,它是 theta 连接的子集 >>,在 sql 术语中是内部连接。

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

关于mysql - SQL中各种join的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30993293/

相关文章:

mysql - 如何从 MySQL 表中获取所有数据组合?

c# - 使用参数从 DbCommand 获取 SQL 查询字符串

mysql - 为什么此查询在 MySQL 5.1.56 中失败?

ruby-on-rails - Rails 嵌套表单 has_many :through, 如何编辑连接模型的属性?

c# - 正在更新 LINQ to SQL,但我的查询来自联接?无法使用使用联接的查询进行更新?

mysql - 如何通过终端查看MySQL用户列表

mysql - 如何将每个 DataGridView 行插入 MYSQL DB

mysql - 两次使用复合键连接表

MySQL - 搜索自连接和范围或数据

基于字段提取值的MYSQL JOIN表