快速简单的过滤器问题。
输出会有什么不同,或者将过滤条件从 WHERE 子句移到 Join 条件中会产生什么影响。
例如:
Select a1.Name, a2.State
from student a1
left join location a2 on a1.name_id = a2.name_id
where a1.name LIKE 'A%'
and a2.state = 'New York';
Run Code Online (Sandbox Code Playgroud)
对此:
Select a1.Name, a2.State
from student a1
left join location a2 on (a1.name_id = a2.name_id) and a2.state = 'New York'
where a1.name LIKE 'A%';
Run Code Online (Sandbox Code Playgroud)
谢谢大家。
a1e*_*x07 11
1) 将显示以“A”开头且位置为纽约的学生姓名。
2) 将显示所有以“A”开头的学生姓名,如果学生所在州是纽约,则显示为“纽约”,否则在其他情况下为空(没有对应的州,或者学生所在州不是纽约)
(1) 和 (2) 之间的区别 - (1) 不会有非纽约学生。
RDF*_*ozz 11
@a1ex07 的答案是完全正确的。但是,让我们提供一个更一般的答案。
当你有一个TableA a LEFT JOIN TableB b
场景时,你必须小心如何TableB
在你的WHERE
子句中使用字段。
对于 中TableA
没有匹配行的任何行TableB
,中的所有字段TableB
都将设置为 NULL。
让我们看看你的例子。
我们假设你想从所有行TableA
(student
),要么在没有匹配的行TableB
(location
),或有一个匹配行TableB
,其中b.Column1
(location.State
)等于“纽约”。
如果您的WHERE
子句包含TableB
对该字段中不允许 NULL 值的字段的检查,则将排除TableA
没有匹配TableB
行的所有行。
示例:WHERE b.State = 'New York'
-TableA
没有匹配TableB
行的行将具有B.Column1
NULL。由于NULL = 'New York'
不是 TRUE,没有匹配( ) 行的TableA
( student
) 行都不符合子句中的条件。TableB
location
WHERE
实际上,这使得LEFT JOIN
一个INNER JOIN
。
如果您确实允许TableB
值为 NULL,则需要注意不允许超过您的意思的值。
如果将上面的示例WHERE
子句更改为:
WHERE (b.State = 'New York' OR b.State IS NULL)
Run Code Online (Sandbox Code Playgroud)
那么TableA
没有匹配TableB
行的行仍将被包括在内。然而,这样将TableA
行与匹配TableB
排在那里Column1
设置为NULL(在你的情况下,student
与匹配的行location
排,其中location.State
为NULL)。这可能不是意图。
要真正满足我们假设的意图,您至少有两个选择:
首先,您可以TableB
对JOIN
条件中的行进行限制:
FROM TableA a
LEFT JOIN TableB b ON (a.name_id = b.name_id AND b.State = 'New York')
Run Code Online (Sandbox Code Playgroud)
这允许通过没有匹配( ) 行的所有TableA
( student
) 行;那里是一个匹配行,从匹配的行和将只包括如果是“纽约”。TableB
location
TableB
TableA
TableB
b.State
其次,在WHERE
子句中包含您的检查,但使用JOIN
in 列TableB
以允许 NULL:
FROM TableA a
LEFT JOIN TableB b ON (a.name_id = b.name_id)
WHERE (b.State = 'New York' OR b.name_id IS NULL)
Run Code Online (Sandbox Code Playgroud)
这假设a.name_id
不能为 NULL。然后,唯一b.name_id
可以为 NULL 的方法是没有找到JOIN
in 的匹配项TableB
。同样,TableA
没有TableB
匹配的行也包括在内(因为b.name_id
这些行将始终为 NULL)。随着我们的假设,其中TableA
有一个匹配TableB
行,b.name_id
将永远为NULL,所以b.State
必须是“纽约”这TableA
并TableB
列入对匹配的行。