内连接顺序

Inner join Order

我有三个表 - A、B 和 C,每个表分别包含 2012 年、2013 年和 2014 年的活跃客户列表。我想获得三年内活跃的客户列表。我是这样做的:

select distinct customer_id
from table_A a
inner join table_B b on a.customer_id=b.customer_id
inner join table_C c on a.customer_id=c.customer_id

但这会给出不同的结果吗:

select distinct customer_id
from table_A a
inner join table_B b on a.customer_id=b.customer_id
inner join table_C c on b.customer_id=c.customer_id

谢谢!

否,因为您正在进行内部联接。内部联接是一个交集,因此无论您将联接放在一起的顺序如何,只有所有 3 个中的 id 才能通过。如果你做一个外连接,你就得担心顺序。

不应该是不同的结果,因为内部连接是一个交集。

这是一个例子。 "empid"1&2是工作满3年的员工

mysql> select * from t2012;
+-------+
| empid |
+-------+
|     1 |
|     2 |
|     3 |
+-------+
3 rows in set (0.00 sec)

mysql> select * from t2013;
+-------+
| empid |
+-------+
|     1 |
|     2 |
|     3 |
|     4 |
+-------+
4 rows in set (0.00 sec)

mysql> select * from t2014;
+-------+
| empid |
+-------+
|     1 |
|     2 |
|     4 |
|     5 |

mysql> select distinct a.empid from t2012 a 
inner join t2013 b on a.empid = b.empid 
inner join t2014 c on a.empid=c.empid;
+-------+
| empid |
+-------+
|     1 |
|     2 |
+-------+
2 rows in set (0.00 sec)

mysql> select distinct a.empid from t2012 a
 inner join t2013 b on a.empid = b.empid
 inner join t2014 c on b.empid=c.empid;
+-------+
| empid |
+-------+
|     1 |
|     2 |
+-------+
2 rows in set (0.00 sec)

inner join 的连接顺序没有区别。

但是,如果 table 之一是 "master" table 每个 customer_id 一行,那么这样做效率更高:

select a.customer_id
from table_A a
where exists (select 1 from table_B b where a.customer_id = b.customer_id) and
      exists (select 1 from table_C c on a.customer_id = c.customer_id);

这消除了 select distinct 的重复缩减。

如果您只想要所有三个表中都存在的客户,您也可以使用集合操作:

select customer_id from table_A
INTERSECT
select customer_id from table_B
INTERSECT
select customer_id from table_C

没有明确的 DISTINCT,但将操作设置为默认值,优化器知道如何最有效地执行此操作。

当然,根据实际情况 data/indexes Gordon 的回答使用 EXISTS 可能会更快。