[SQL] 절은 같은 왼쪽에 일치하지 않는 WHERE 왼쪽이에 조건 가입 할 때 ON에 왜와 가입? [복제]
SQL절은 같은 왼쪽에 일치하지 않는 WHERE 왼쪽이에 조건 가입 할 때 ON에 왜와 가입? [복제]
나는 나의가 SQL 서버에 조인 내 모든 이해를 의심하게하는 매우 혼란 상황을 경험하고있다.
SELECT t1.f2
FROM t1
LEFT JOIN t2
ON t1.f1 = t2.f1 AND cond2 AND t2.f3 > something
동일한 결과를로 제공하지 않습니다 :
SELECT t1.f2
FROM t1
LEFT JOIN t2
ON t1.f1 = t2.f1 AND cond2
WHERE t2.f3 > something
이 두 개의 쿼리가 동등하다고 가정이나하지 않으면 이야기가 다른 사람의 도움을 기쁘게 할 수 있습니까?
고마워
해결법
-
==============================
1.(가) 행 일치를 찾고 가입 할 때 절에 사용됩니다. WHERE 절은 모든 가입 완료 후 필터 행에 사용됩니다.
(가) 행 일치를 찾고 가입 할 때 절에 사용됩니다. WHERE 절은 모든 가입 완료 후 필터 행에 사용됩니다.
대통령 투표 디즈니 만화 영화와 예 :
declare @candidates table (name varchar(50)); insert @candidates values ('Obama'), ('Romney'); declare @votes table (voter varchar(50), voted_for varchar(50)); insert @votes values ('Mickey Mouse', 'Romney'), ('Donald Duck', 'Obama'); select * from @candidates c left join @votes v on c.name = v.voted_for and v.voter = 'Donald Duck'
도널드 그를 위해 투표하지 않은 경우에도이 여전히 롬니를 반환합니다. 당신은 where 절에에에서 상태를 이동하는 경우 :
select * from @candidates c left join @votes v on c.name = v.voted_for where v.voter = 'Donald Duck'
롬니는 더 이상 결과 집합에 없습니다.
-
==============================
2.모두 그대로 다릅니다.
모두 그대로 다릅니다.
첫 번째 쿼리는 테이블의 결합 전에 T2 테이블의 필터링이 수행한다. 결과는 다음 T1의 모든 레코드를 결과 테이블 t1에 가입 할 수 있도록 목록에 표시됩니다.
조인 테이블 후 전체 결과에서 두 번째 필터가 이루어집니다.
다음은 그 예이다
1 번 테이블
ID Name 1 Stack 2 Over 3 Flow
표 2
T1_ID Score 1 10 2 20 3 30
첫 번째 쿼리에서는 다음과 같습니다,
SELECT a.*, b.Score FROM Table1 a LEFT JOIN Table2 b ON a.ID = b.T1_ID AND b.Score >= 20
그것이 무엇을하면 테이블을 조인하기 전에이며, 표 2의 기록은 점수에 의해 처음으로 필터링됩니다. 표에 합류 할 수있는 유일한 기록은 그래서
T1_ID Score 2 20 3 30
T1_ID의 점수는 10이기 때문에 쿼리의 결과는
ID Name Score 1 Stack NULL 2 Over 20 3 Flow 30
두 번째 쿼리는 다르지만.
SELECT a.*, b.Score FROM Table1 a LEFT JOIN Table2 b ON a.ID = b.T1_ID WHERE b.Score >= 20
그것은 일치하는 레코드 다른 테이블에 여부가 있는지 여부를 먼저 기록을 결합한다. 결과가 될 것입니다 그래서
ID Name Score 1 Stack 10 2 Over 20 3 Flow 30
상기 필터링 일어난다 b.Score> = 20, 최종 결과가 될 수 있도록
ID Name Score 2 Over 20 3 Flow 30
-
==============================
3.첫 번째 경우에는 T2의 결과 결합의 일부로서 필터링된다.
첫 번째 경우에는 T2의 결과 결합의 일부로서 필터링된다.
두 번째 경우, T2에서 사용할 수 많은 행이있을 수 있습니다.
기본적으로, 레코드의 집합은 동일하지 않습니다 두 개의 쿼리에 합류했다.
-
==============================
4.그것은 두 번째 경우에 당신이 왼쪽 않습니다 후에 어디에 가입 적용되기 때문에 변화를 않습니다
그것은 두 번째 경우에 당신이 왼쪽 않습니다 후에 어디에 가입 적용되기 때문에 변화를 않습니다
-
==============================
5.
CREATE TABLE Company ( CompanyId TinyInt Identity Primary Key, CompanyName Nvarchar(50) NULL ) GO INSERT Company VALUES('DELL') INSERT Company VALUES('HP') INSERT Company VALUES('IBM') INSERT Company VALUES('Microsoft') GO CREATE TABLE Candidate ( CandidateId tinyint identity primary key, FullName nvarchar(50) NULL, CompanyId tinyint REFERENCES Company(CompanyId) ) GO INSERT Candidate VALUES('Ron',1) INSERT Candidate VALUES('Pete',2) INSERT Candidate VALUES('Steve',3) INSERT Candidate VALUES('Steve',NULL) INSERT Candidate VALUES('Ravi',1) INSERT Candidate VALUES('Raj',3) INSERT Candidate VALUES('Kiran',NULL) GO SELECT * from Company c SELECT * from Candidate c -- A simple left outer Join SELECT * FROM Company c LEFT OUTER JOIN Candidate c2 ON c.CompanyId = c2.CompanyId --Left Outer Join ON and AND condition fetches 5 rows wtih NULL value from right side table SELECT * FROM Company c LEFT OUTER JOIN Candidate c2 ON c.CompanyId = c2.CompanyId AND c.CompanyName = 'DELL' --Left Outer Join ON and where clause fetches only required rows SELECT * FROM Company c LEFT OUTER JOIN Candidate c2 ON c.CompanyId = c2.CompanyId AND c.CompanyName = 'DELL' WHERE c.CompanyName='IBM'
from https://stackoverflow.com/questions/15706112/why-and-when-a-left-join-with-condition-in-where-clause-is-not-equivalent-to-the by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 두 소수와 다수가 SQL 서버를 배치 쓰기 (0) | 2020.04.10 |
---|---|
[SQL] SQL 여러 테이블에 LINQ는 외부 조인 왼쪽 (0) | 2020.04.10 |
[SQL] 어떻게? 매개 변수 및 LIKE 문 SQL (0) | 2020.04.10 |
[SQL] 우리는 두 개의 서로 다른 데이터베이스 테이블에 가입 할 수 있습니까? (0) | 2020.04.10 |
[SQL] VARCHAR에 캐스트 INT (0) | 2020.04.10 |