什么区别
SELECT DISTINCT field1
FROM table1 cd
JOIN table2
ON cd.Company = table2.Name
and table2.Id IN (2728)
Run Code Online (Sandbox Code Playgroud)
和
SELECT DISTINCT field1
FROM table1 cd
JOIN table2
ON cd.Company = table2.Name
where table2.Id IN (2728)
Run Code Online (Sandbox Code Playgroud)
两者都返回相同的结果,两者都有相同的解释输出
Mar*_*ers 30
首先是语义上的差异.如果有连接,则表示两个表之间的关系由该条件定义.所以在你的第一个例子中,你说这些表是相关的cd.Company = table2.Name AND table2.Id IN (2728).当您使用WHERE子句时,您说的是关系是由定义的,cd.Company = table2.Name并且您只需要条件table2.Id IN (2728)适用的行.尽管这些答案给出了相同的答案,但对于程序员阅读代码来说,这意味着完全不同的东西.
在这种情况下,WHERE子句几乎肯定是你的意思所以你应该使用它.
其次,在使用LEFT JOIN而不是INNER JOIN的情况下,结果实际上存在差异.如果将第二个条件作为连接的一部分包含在内,则在条件失败时仍将获得结果行 - 您将从左表中获取值,并为右表获取空值.如果将条件包含在WHERE子句中并且该条件失败,则根本不会获取该行.
这是一个证明这一点的例子.
查询1(WHERE):
SELECT DISTINCT field1
FROM table1 cd
LEFT JOIN table2
ON cd.Company = table2.Name
WHERE table2.Id IN (2728);
Run Code Online (Sandbox Code Playgroud)
结果:
field1
200
Run Code Online (Sandbox Code Playgroud)
查询2(AND):
SELECT DISTINCT field1
FROM table1 cd
LEFT JOIN table2
ON cd.Company = table2.Name
AND table2.Id IN (2728);
Run Code Online (Sandbox Code Playgroud)
结果:
field1
100
200
Run Code Online (Sandbox Code Playgroud)
使用的测试数据:
CREATE TABLE table1 (Company NVARCHAR(100) NOT NULL, Field1 INT NOT NULL);
INSERT INTO table1 (Company, Field1) VALUES
('FooSoft', 100),
('BarSoft', 200);
CREATE TABLE table2 (Id INT NOT NULL, Name NVARCHAR(100) NOT NULL);
INSERT INTO table2 (Id, Name) VALUES
(2727, 'FooSoft'),
(2728, 'BarSoft');
Run Code Online (Sandbox Code Playgroud)
SQL来自关系代数.
查看差异的一种方法是JOIN是对集合的操作,可以在结果中生成比原始表中更多的记录或更少的记录.另一方面,WHERE将始终限制结果的数量.
本文的其余部分是额外的解释.
有关连接类型的概述,请再次阅读文章.
当我说where条件总是会限制结果时,你必须考虑到当我们讨论两个(或更多)表上的查询时,你必须以某种方式配对这些表中的记录,即使没有JOIN关键字.
所以在SQL中,如果表只是用逗号分隔,那么实际上你正在使用一个CROSS JOIN(笛卡尔积),它返回另一个表中每一行的每一行.
并且由于这是来自两个表的行的最大组合数,因此交叉连接表上的任何WHERE的结果可以表示为JOIN操作.
但是,当你引入LEFT,RIGHT和FULL OUTER连接时,这个最大值有例外.
LEFT JOIN将使用右表中的记录将左表中的记录与给定条件的记录连接起来,但是如果连接条件,查看左表中的一行不满足右表中的任何记录,LEFT JOIN仍将返回来自左表和来自右表的列中的记录将返回NULL(RIGHT JOIN的工作方式类似但是从另一侧起,FULL OUTER同时起作用).
由于默认的交叉连接不返回那些记录,你不能用WHERE条件表达这些连接标准,并且你被迫使用JOIN语法(oracle是一个例外,带有SQL标准的扩展和to =运算符,但这不是被其他供应商接受,也没有标准).
此外,连接通常(但并非总是)与现有的参照完整性一致,并建议实体之间的关系,但我不会给予那么多的重视因为条件可以做同样的事情(除了前面提到的情况)和一个好的RDBMS在您指定标准的地方不会产生任何影响.