这两个sql命令有什么区别?

时间:2012-05-24 14:49:02

标签: sql

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 个答案:

答案 0 :(得分:9)

这是INNER JOIN没有区别,但如果您使用OUTER JOIN,结果将会大不相同。与LEFT OUTER JOIN一起使用时,第二个查询将隐式变为INNER JOIN

通过使用AND,谓词识别s中的行应该何时连接到n。在内连接中,这里的否定结果将阻止n和s侧被省略。

答案 1 :(得分:2)

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

答案 2 :(得分:2)

这里有一些关于这个主题的有趣讨论:

INNER JOIN ON vs WHERE clause

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

答案 3 :(得分: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的信息。