복붙노트

[SQL] 왼쪽은 내부에 회전이 조인

SQL

왼쪽은 내부에 회전이 조인

SELECT
a.foo
b.bar
c.foobar
FROM tableOne AS a
INNER JOIN tableTwo AS b ON a.pk = b.fk
LEFT JOIN tableThree AS c ON b.pk = c.fk
WHERE a.foo = 'something'
AND c.foobar = 'somethingelse'

절은 왼쪽을 설정하는 것 같은 곳 후와 절을 갖는 가입 내부에 가입 할 수 있습니다. 밤은 'SOMETHINGELSE'에서 tableThree 0 행이 반환이있을 것입니다 경우 내가보고 있어요 동작입니다.

FROM 절 저장된 가입에 내가 이동 c.foobar = 'SOMETHINGELSE'경우 왼쪽 가입을 같은 역할을 가입 할 수 있습니다.

    SELECT
    a.foo
    b.bar
    c.foobar
    FROM tableOne AS a
    INNER JOIN tableTwo AS b ON a.pk = b.fk
    LEFT JOIN tableThree AS c ON b.pk = c.fk
    AND c.foobar = 'somethingelse'
    WHERE a.foo = 'something'

이런 이유를 설명하는 몇 가지 문서에서 누군가 포인트 나를 수 있습니까? 정말 감사합니다

해결법

  1. ==============================

    1.이 때문에 당신의 WHERE 절에의합니다.

    이 때문에 당신의 WHERE 절에의합니다.

    당신이 왼쪽 오른쪽에서 값을 지정할 때마다 WHERE 절에 조인 (NULL이되지 않는), 당신은 반드시 NULL 값을 모두 제거하고 그것은 기본적으로 내부 조인된다.

    당신이 작성하는 경우, AND (c.foobar = 'SOMETHINGELSE'OR c.foobar가 null) 문제를 해결할 것이다.

    당신은 또한 당신의 가입 조건에 c.foobar 부분을 이동할 수 있습니다, 너무 문제가 해결됩니다.

  2. ==============================

    2.왼쪽은 C에 존재하지 않는 행을 NULL로 세트를 C의 모든 열을 가입하기 때문에 당신이보고있는 이유는 (즉, 결합 할 수 없습니다). 이 비교 c.foobar = 'SOMETHINGELSE은'그 행이 반환되지 않는 이유입니다, 사실이 아니다는 것을 의미한다.

    왼쪽은 C에 존재하지 않는 행을 NULL로 세트를 C의 모든 열을 가입하기 때문에 당신이보고있는 이유는 (즉, 결합 할 수 없습니다). 이 비교 c.foobar = 'SOMETHINGELSE은'그 행이 반환되지 않는 이유입니다, 사실이 아니다는 것을 의미한다.

    조건이 true가 아닌 경우 여전히 그 행을 반환 (NULL 값이기는하지만) 조인은 조인 조건에 c.foobar = 'SOMETHINGELSE'을 이동할 경우,합니다.

  3. ==============================

    3.조인 후 '어디에'조항이 수행됩니다. 내부 조인하지만 외부 조인에 대한 문제에 대해이 문제가되지 않습니다.

    조인 후 '어디에'조항이 수행됩니다. 내부 조인하지만 외부 조인에 대한 문제에 대해이 문제가되지 않습니다.

    를 단축 예

    SELECT b.bar,c.foobar FROM tableTwo AS b LEFT JOIN tableThree AS c ON b.pk=c.fk WHERE c.foobar='somethingelse'
    
    Raw data                  Outer Join Result        Select Result
    b.pk c.fk c.foorbar       b.pk c.fk c.foorbar      c.foorbar
    1    1    something       1    1    something      <not in result set>
    1    1    somethingelse   1    1    somethingelse  somethingelse
    
    
    SELECT b.bar,c.foobar FROM tableTwo AS b LEFT JOIN tableThree AS c ON b.pk=c.fk AND c.foobar='somethingelse'
    
    Raw data                  Outer Join Result        Select Result
    b.pk c.fk c.foorbar       b.pk c.fk c.foorbar      c.foorbar
    1    1    something       1    null null           null
    1    1    somethingelse   1    1    somethingelse  somethingelse
    
  4. ==============================

    4.다음 위치를 기록 c.foobar <> 'SOMETHINGELSE'을 제거하고, 자신의 일을 조인.

    다음 위치를 기록 c.foobar <> 'SOMETHINGELSE'을 제거하고, 자신의 일을 조인.

    내부와 같은 효과의 외모에 가입하지만 실제로는 아니다.

  5. ==============================

    5.왼쪽은 (귀하의 예제에서 tableTwo) 왼쪽 테이블에서 반환 모든 오른쪽 (귀하의 예제에서 tableThree)에있는 테이블에서 일치하는 행을하세요. 왼쪽의 오른쪽에 뭔가를 필터링 할 때 효과적으로 요구되는 값에 가입 (즉 tableThree)과는 일치하지 않는 고려하지 않는 값이 존재하고 값은 내부의 동등 '뭔가'를하는 것이 붙다. 당신이 일을하려고하는 것은 '무언가'의는 foobar 값 tableThree의 행이없는 모든 tableTwo 행을 찾을 경우, 당신은 절에로 필터링을 이동할 수 있습니다 :

    왼쪽은 (귀하의 예제에서 tableTwo) 왼쪽 테이블에서 반환 모든 오른쪽 (귀하의 예제에서 tableThree)에있는 테이블에서 일치하는 행을하세요. 왼쪽의 오른쪽에 뭔가를 필터링 할 때 효과적으로 요구되는 값에 가입 (즉 tableThree)과는 일치하지 않는 고려하지 않는 값이 존재하고 값은 내부의 동등 '뭔가'를하는 것이 붙다. 당신이 일을하려고하는 것은 '무언가'의는 foobar 값 tableThree의 행이없는 모든 tableTwo 행을 찾을 경우, 당신은 절에로 필터링을 이동할 수 있습니다 :

    Select a.foo, b.bar, c.foobar
    From tableOne As a
        Inner Join tableTwo as b
            On b.fk = a.pk
        Left Join tableThree as c
            On c.fk = b.pk
                And c.foobar = 'something'
    Where a.foo = 'something'
        And c.pk Is Null
    

    마지막 추가, c.pk는 (그렇지 않으면 및 널 (null)) '뭔가'단지 그들이의는 foobar의 값을 가질 때 tableThree 값을 표시 할 something'.If '의는 foobar의 값으로 tableThree 값이없는 값을 널 필터가 다음 c.pk는 null의 추가 추가 필터 I를 제거합니다.

  6. ==============================

    6.(가) (가 올바르게 발생) 발생 한 조인 후 c.foobar에 의해 필터링합니다 (c.foobar이 where 절에) 첫번째 사건이 발생하면 효과적으로 필터 아웃 모든 결과 기록이 수행하지 않은 'SOMETHINGELSE'때문에 거기에..

    (가) (가 올바르게 발생) 발생 한 조인 후 c.foobar에 의해 필터링합니다 (c.foobar이 where 절에) 첫번째 사건이 발생하면 효과적으로 필터 아웃 모든 결과 기록이 수행하지 않은 'SOMETHINGELSE'때문에 거기에..

    이 접합 시간에 평가하고 단지 가입의 출력을 제어하고 있지 최종 레코드 (조인 returnsnull 실패) 따라서 2 케이스 c.foobar는 가입의 부분이다 ..

  7. ==============================

    7.LEFT이 조인은 일치하는 행이없는 널 (null)을 생산하고 있습니다. 이 경우, c.foobar 비 매칭 행에 대해 NULL이 될 것이다. 'SOMETHINGELSE'등 모든 NULL 값을 걸러 :하지만 당신의 WHERE 절은 특정 값을 찾고있다. 내부 조인하기 때문에 또한 우측에는 NULL 값을 생성하지 개의 동일한 본다. 당신은 추가 할 수 있습니다 '또는 c.foobar은 NULL IS'널 값이 다시 허용 할 수 있습니다.

    LEFT이 조인은 일치하는 행이없는 널 (null)을 생산하고 있습니다. 이 경우, c.foobar 비 매칭 행에 대해 NULL이 될 것이다. 'SOMETHINGELSE'등 모든 NULL 값을 걸러 :하지만 당신의 WHERE 절은 특정 값을 찾고있다. 내부 조인하기 때문에 또한 우측에는 NULL 값을 생성하지 개의 동일한 본다. 당신은 추가 할 수 있습니다 '또는 c.foobar은 NULL IS'널 값이 다시 허용 할 수 있습니다.

    당신은 ON 절에 조건을 이동하면 조인 행 일치가 아닌 최종 필터의 일부가됩니다. 는 일치에 실패 할 수 있습니다 가입하고, 외부는 'c.foobar가'SOMETHINGELSE 'NULL인지 경우 다음의 경우에 null을 리턴 가입 할 수 있습니다.

    보다

  8. ==============================

    8.내부 조인에 LEFT JOIN을 설정하지 않고, 효과가 동일하게 나타날 수 있습니다 생각했다. 당신은 WHERE 조건을 설정하는 경우

    내부 조인에 LEFT JOIN을 설정하지 않고, 효과가 동일하게 나타날 수 있습니다 생각했다. 당신은 WHERE 조건을 설정하는 경우

    당신이 LEFT 수 있도록 모든 경우를 제거 얻고있는 것은이하는 역할을 가입하세요. 이 경우, c.foobar에 대한 일부 값은 NULL이됩니다. 조인 조건에서이 설정은 여전히 ​​일치하지 않는 LEFT는 C 결과를 반환되는 것을 제한하는 결과를 가입 할 수 있습니다.

  9. from https://stackoverflow.com/questions/3256304/left-join-turns-into-inner-join by cc-by-sa and MIT license