1
select * from StudySQL.dbo.id_name n
inner join StudySQL.dbo.id_sex s
on n.id=s.id
and s.sex='f'

select * from StudySQL.dbo.id_name n
inner join StudySQL.dbo.id_sex s
on n.id=s.id
where s.sex='f'

结果是一样的。那么它们之间有什么区别吗?

添加

我做了几次更有趣的尝试。

select * from StudySQL.dbo.id_name n

1 | baby
3 | alice

select * from StudySQL.dbo.id_class c

1 | math      
3 | physics   
3 | english   
4 | chinese 


select * from StudySQL.dbo.id_name n
left join StudySQL.dbo.id_class c
on n.name='alice'

name  id    id  class
baby    1   NULL    NULL
alice   3   1           math      
alice   3   3           physics   
alice   3   3           english   
alice   3   4           chinese   


select * from StudySQL.dbo.id_name n
left join StudySQL.dbo.id_class c
on n.name='baby'

name    id  id  class
baby    1   1           math      
baby    1   3           physics   
baby    1   3           english   
baby    1   4           chinese   
alice   3   NULL    NULL


select * from StudySQL.dbo.id_name n
left join StudySQL.dbo.id_class c
on n.name<>''

name    id  id  class
baby   1    1           math      
baby   1    3           physics   
baby   1    3           english   
baby   1    4           chinese   
alice  3    1           math      
alice  3    3           physics   
alice  3    3           english   
alice  3    4           chinese   

所以我认为可以合理地说,on 子句决定了哪些行应该被连接。而 where 子句决定应该返回哪些行

如果这是真的,我认为最好在 on 子句中编写详细的限制,以便需要连接的行更少。因为连接是一项昂贵的操作。

4

4 回答 4

9

虽然这是一个没有区别,INNER JOIN但如果你使用一个结果会非常不同OUTER JOIN。与LEFT OUTER JOIN第二个查询一起使用将隐式变为INNER JOIN.

通过使用AND谓词来确定何时应将 s 中的行连接到 n。在内部连接中,这里的否定结果将阻止 n 和 s 边都被省略。

于 2012-05-24T14:50:05.950 回答
2

ON 子句用于指定表之间的关系,WHERE 子句用于指定过滤条件。在这种情况下,结果/性能问题可能更像是一个概念问题。

于 2012-05-24T14:59:54.253 回答
2

在这里可以找到有关此主题的一些有趣的讨论:

INNER JOIN ON vs WHERE 子句

它们应始终返回相同的结果,但可能会由于删除过滤行的时间而导致查询计划和性能略有不同。此行为将取决于您使用的服务器。

于 2012-05-24T15:10:10.223 回答
1

就像 Marc Romero 说的,ON 子句是指定表之间的关系,WHERE 子句是指定过滤条件。在此特定查询中,您将看到相同的结果,但在其他查询中,如果您不了解差异,您可能会得到意想不到的结果。考虑下面的查询(使用 LEFT JOINS 而不是 INNER):

SELECT *
FROM StudySQL.dbo.id_name n
LEFT JOIN StudySQL.dbo.id_sex s ON n.id=s.id AND s.sex='f'

SELECT *
FROM StudySQL.dbo.id_name n
LEFT JOIN StudySQL.dbo.id_sex s on n.id=s.id
WHERE s.sex='f'

第一个将返回来自 StudySQL.dbo.id_name 的信息以及来自 StudySQL.dbo.id_sex 表中与任何具有性别“f”的记录相关联的信息。第二个将返回所有名称,但只有性别为“f”的名称才会填充来自 StudySQL.dbo.id_sex 的信息。

于 2012-05-24T15:49:58.710 回答