SQL表连接中ON和WHERE子句之间的区别

时间:2012-10-30 03:58:51

标签: sql oracle join

select e.last_name, e.hire_date
from employees e join employees m
on (m.last_name = 'Davies')
and (e.hire_date > m.hire_date);

select e.last_name, e.hire_date
from employees e join employees m
on (m.last_name = 'Davies')
where (e.hire_date > m.hire_date);

select e.last_name, e.hire_date
from employees e join employees m
on (e.hire_date > m.hire_date)
where (m.last_name = 'Davies');

这三个陈述具有相同的结果。除了where不能单独使用on而不使用where这一事实外,是否有任何特殊原因在表连接中使用{{1}}?

5 个答案:

答案 0 :(得分:11)

主要区别在于您使用不同的连接时。

通常,如果要使用内部联接,应该会看到相同的结果,但是一旦开始使用LEFT联接,结果就会发生变化。

看一下以下示例

SQL Fiddle DEMO

And have a look at the following article (very explanatory)

编辑@ShannonSeverance

架构和测试数据

CREATE TABLE Table1 (
  ID INT,
  Val VARCHAR(20)
 );

INSERT INTO Table1 VALUES (1,'a');
INSERT INTO Table1 VALUES (2,'a');

CREATE TABLE Table2 (
  ID INT,
  Val VARCHAR(20)
 );

INSERT INTO Table2 VALUES (1,'a');

和测试

SELECT t1.ID,
t1.Val,
t2.ID ID2,
t2.Val Val2
FROM Table1 t1 INNER JOIN
Table2 t2 ON t1.ID = t2.ID AND t1.Val = t2.Val;

SELECT  t1.ID,
t1.Val,
t2.ID ID2,
t2.Val Val2
FROM Table1 t1,Table2 t2 
WHERE t1.ID = t2.ID
 AND t1.Val = t2.Val;

SELECT  t1.ID,
t1.Val,
t2.ID ID2,
t2.Val Val2
FROM Table1 t1 LEFT JOIN
Table2 t2 ON t1.ID = t2.ID  AND t1.Val = t2.Val;

SELECT  t1.ID,
t1.Val,
t2.ID ID2,
t2.Val Val2
FROM Table1 t1 LEFT JOIN
Table2 t2 ON t1.ID = t2.ID  
WHERE t1.Val = t2.Val;

答案 1 :(得分:10)

where是使用连接选择行后应用的过滤器。并非总是join ... on条件在语义上等同于where条件。因此,是的,有一个特殊的理由在表连接中使用where:当它做正确的事情时。


  

...相反,ON条件在进行连接时执行。多表连接中较早连接的ON条件可以切断数百万个不必要的连接,因此如果语义正确,通常首选    - Bohemian

答案 2 :(得分:1)

使用on通常用于查询多个表。在进行该查询时,表必须彼此具有关系,通常在特定字段中具有相同的值。

on将连接相同的值,例如:

**table1**:

id_name   id_position   name
1         1             john
2         2             doe
3         2             tom
4         3             hawkins

**table2**
id_position   position
1             system analyst
2             programmer

SELECT t1.id_name, t1.name, t2.position
  FROM table1 t1 LEFT JOIN table2 t2
  ON t1.id_position = t2.id_position

-- RESULT:
id_name   name     position
1         john     system analyst
2         doe      programmer
3         tom      programmer
4         hawkins  NULL            -- NO MATCH IN table 2

我们可以看到on将连接具有相同值id_position的table1和table2,因此它与您上面的内容略有不同。

虽然where可以在每个查询中使用,但不取决于该查询中有多少个表。通常where用于我们想要的条件事件。

答案 3 :(得分:0)

不同之处在于引擎何时执行过滤。 “where”表示两个表的计算乘积上的过滤器。 “on”关键字指定如何执行连接。即使有时它们都产生相同的结果,它们在语义上也是等价的。

干杯

答案 4 :(得分:0)

ON子句定义了表之间的关系。

  • ON子句支持所有连接类型。

WHERE子句描述了您感兴趣的行。

  • WHERE条款仅支持内部联接,不支持LEFT JOINRIGHT JOIN等外部联接。