JOIN子句与WHERE子句相比较

时间:2016-07-19 01:38:42

标签: sql sql-server left-join where-clause

当我运行以下两个查询时,我得到两个不同的答案。我真的很想知道为什么。它是LEFT JOIN吗?这是运营的顺序吗?这可能发生在其他JOIN类型中吗?

第一次查询

SELECT
First_Name
, E.Employee_ID
, I.Employee_REF_ID
FROM Employee AS E
LEFT JOIN Incentives AS I
ON (E.Employee_ID = I.Employee_REF_ID)  AND (I.Employee_Ref_Id IS NOT NULL);

输出

1.  First_Name  Employee_ID Employee_REF_ID
2.  John    1   1
3.  John    1   1
4.  Michael 2   2
5.  Michael 2   2
6.  Roy 3   3
7.  Tom 4   NULL
8.  Jerry   5   NULL
9.  NULL    6   NULL
10. TestName1   7   NULL
11. Lname%  8   NULL

第二次查询

SELECT
First_Name
, E.Employee_ID
, I.Employee_REF_ID
   FROM Employee AS E
LEFT JOIN Incentives AS I
ON (E.Employee_ID = I.Employee_REF_ID)  
WHERE I.Employee_Ref_Id IS NOT NULL;

输出

1.  First_Name  Employee_ID Employee_REF_ID
2.  John    1   1
3.  Michael 2   2
4.  Roy 3   3
5.  John    1   1
6.  Michael 2   2

来自http://narendra86.blogspot.com/2013/10/top-80-sql-query-interview-questions.html的原始代码

4 个答案:

答案 0 :(得分:1)

以此为例:

declare @table1 table (emp_id int, name varchar(10))
declare @table2 table (emp_ref_id int, ref_name varchar(10))

insert into @table1 values (1, 'emp1'), (2, 'emp2'), (3, 'emp3')
insert into @table2 values (1, 'empref1'), (2, 'empref2')

此查询:

select *
from @table1 t1
left join @table2 t2 on t1.emp_id = t2.emp_ref_id and t2.emp_ref_id is not null

返回:

emp_id  name    emp_ref_id  ref_name
1       emp1    1           empref1
2       emp2    2           empref2
3       emp3    NULL        NULL

但是这个查询:

select *
from @table1 t1
left join @table2 t2 on t1.emp_id = t2.emp_ref_id
where t2.emp_ref_id is not null

返回:

emp_id  name    emp_ref_id  ref_name
1       emp1    1           empref1
2       emp2    2           empref2

不同之处在于,在第一个查询中t2.emp_ref_id is not null条件没有效果,因为它是左连接,所以即使右表没有匹配的行,这些列也将返回null 。在第二个查询中,将根据查询返回的条件检查条件t2.emp_ref_id is not null,以便删除null emp_ref_id的行。

另一个例子:

declare @table1 table (emp_id int, name varchar(10))
declare @table2 table (emp_ref_id int, ref_name varchar(10), col3 varchar)

insert into @table1 values (1, 'emp1'), (2, 'emp2'), (3, 'emp3')
insert into @table2 values (1, 'empref1', 'a'), (2, 'empref2', null)

select *
from @table1 t1
left join @table2 t2 on t1.emp_id = t2.emp_ref_id and t2.col3 is not null

将返回:

emp_id  name    emp_ref_id  ref_name    col3
1       emp1    1           empref1     a
2       emp2    NULL        NULL        NULL
3       emp3    NULL        NULL        NULL

如果您使用此查询:

select *
from @table1 t1
left join @table2 t2 on t1.emp_id = t2.emp_ref_id 

它返回:

emp_id  name    emp_ref_id  ref_name    col3
1       emp1    1           empref1     a
2       emp2    2           empref2     NULL
3       emp3    NULL        NULL        NULL

正如你所看到的,因为它是一个左连接,当你有条件and t2.col3 is not null时,它只是意味着左连接找不到与@ table2相匹配的行,但仍然会返回table2,具有空值。

答案 1 :(得分:0)

{ "SpotPriceHistory": [] } 允许您根据您设置的条件将第二个表链接到第一个表。

在您的第一个查询中, 如果没有匹配,JOIN将为您提供加入的表LEFT JOIN中的所有列。

在您的第二个查询中,您的NULL子句进一步删除了那些不匹配的记录,因此没有WHERE的记录。

如果您可以在表格上提供样本数据,那么会给您更好的解释。

答案 2 :(得分:0)

由于Left join的计算方式,您的结果会有所不同 - 在ON子句中包含条件可能会产生与WHERE子句中的等效条件不同的结果(当您有ON子句 - 当没有匹配时,我们在右侧得到NULL,但在WHERE子句中,行被过滤掉了。

查看此stackoverflow答案以获取更多详细信息 - SQL join: where clause vs. on clause

答案 3 :(得分:-2)

您应该使用ORDER BY子句来强制所需的订单。例如:

SELECT
First_Name
, E.Employee_ID
, I.Employee_REF_ID
FROM Employee AS E
LEFT JOIN Incentives AS I
ON (E.Employee_ID = I.Employee_REF_ID)  AND (I.Employee_Ref_Id IS NOT NULL)
ORDER BY First_Name ASC;