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子句中编写详细的限制,以便需要连接更少的行。因为连接是一项昂贵的操作。
答案 0 :(得分:9)
这是INNER JOIN
没有区别,但如果您使用OUTER JOIN
,结果将会大不相同。与LEFT OUTER JOIN
一起使用时,第二个查询将隐式变为INNER JOIN
。
通过使用AND
,谓词识别s中的行应该何时连接到n。在内连接中,这里的否定结果将阻止n和s侧被省略。
答案 1 :(得分:2)
ON子句用于指定表之间的关系,WHERE子句用于指定过滤条件。在这种情况下,这可能是一个概念问题,即结果/性能问题。
答案 2 :(得分:2)
这里有一些关于这个主题的有趣讨论:
它们应始终返回相同的结果,但由于删除过滤的行时,可能会导致略有不同的查询计划和性能。此行为将取决于您正在使用的服务器。
答案 3 :(得分:1)
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的信息。