内连接订单

时间:2016-03-25 00:29:21

标签: mysql sql teradata proc

我有三个表--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

谢谢!

4 个答案:

答案 0 :(得分:2)

inner join的联接顺序没有任何区别。

但是,如果其中一个表是“主”表,每个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的重复减少。

答案 1 :(得分:1)

不,因为你正在进行内部联接。内部联接是一个交集,所以只有所有3个中的id才能通过,无论你将联接放在一起的顺序如何。如果您进行外部联接,则必须更加关注订单。

答案 2 :(得分:1)

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

这是一个例子。 “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)

答案 3 :(得分:1)

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

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

没有明确的DISTINCT,但设置操作默认为它,优化器知道如何最有效地完成它。

当然,根据实际数据/索引,Gordon使用EXISTS的答案可能会更快。