복붙노트

[SQL] 절과 절에서 테이블 조인을 떠날 때 경우의 차이점은 무엇입니까?

SQL

절과 절에서 테이블 조인을 떠날 때 경우의 차이점은 무엇입니까?

SQL1 :

select t1.f1,t2.f2 
from t1 
   left join t2 on t1.f1 = t2.f2 and t1.f2=1 and t1.f3=0 

SQL2 :

select t1.f1,t2.f2 
from t1 
  left join t2 on t1.f1 = t2.f2 
where t1.f2=1 and t1.f3=0

차이점은,이 같은 반환 결과는 어디 절에 무엇입니까? 과의 차이는 무엇인가? DBMS는 그들에게 같은 방법으로 실행 하는가? 감사.

해결법

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

    1.WHERE 절은 전체 결과 집합에 적용; (가) 문제의 가입에 온 절에만 적용됩니다.

    WHERE 절은 전체 결과 집합에 적용; (가) 문제의 가입에 온 절에만 적용됩니다.

    주어진 예에서, 가입의 내측에 분야에 관한 추가적인 조건이 모두 - 그래서이 예에서, 두 개의 쿼리 효과적으로 동일하다.

    당신이 가입의 바깥 쪽의 테이블에 값에 대한 조건을 포함했다 그러나, 그것은 상당한 차이를 만들었을 것입니다.

    http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause : 당신은이 링크에서 자세한 내용을 얻을 수 있습니다

    예를 들면 :

    select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 and t2.f4=1
    
    select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 where t2.f4=1
    

    - 다른 것들을 - 내부는 T2로 조인 후자 효과적으로 다시 설정 하였지만 전 의지, F4가 1 T2 레코드 가입 떠났다.

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

    2.(가) 조건이 두 번째보다 더 구체적 조인으로 첫 번째 쿼리가 더 빨리 두 번째보다 : 그것은 당신이 where 절에 필터링 할 것이라는 점을 반환 기록에 의미가 없습니다 (이것은 모든 - 쿼리 1에이를 반환하지 않는 더 나은 것 )

    (가) 조건이 두 번째보다 더 구체적 조인으로 첫 번째 쿼리가 더 빨리 두 번째보다 : 그것은 당신이 where 절에 필터링 할 것이라는 점을 반환 기록에 의미가 없습니다 (이것은 모든 - 쿼리 1에이를 반환하지 않는 더 나은 것 )

    어쨌든 정말 쿼리 최적화 따라 달라집니다.

    아래를 보라 :

    A는 빠르게 WHERE 이상의 조인?

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

    3.두 쿼리는 동일하지 않습니다.

    두 쿼리는 동일하지 않습니다.

    마크 베니 스터는 where 절은 전체 결과 집합에 적용되지만 절에 조인을 적용한다는 지적에 맞았다.

    SQL 1 좌 조건을 가입하기 위해 귀하의 경우, 필터는 오른쪽에 참여하지만, 필터링 WHERE 왼쪽은 항상 어떤 전에 반환됩니다. 더 있기 때문에 모든 T1의 조건은 항상 반환되지이다.

    SQL 2에서 왼쪽 조건 필터를 오른쪽에 보여주는 몇 가지 결과를 가입하지만, 모든 것을 다시 T1이 반환됩니다. 하지만 이번에는 상황이 떨어져 T1의 일부 레코드를 필터링 할 수있다 WHERE.

    INSERT INTO`t1` (f1```f2``f3`) VALUES (1,1,1); INSERT INTO`t2` (`f3`) VALUES (1);

    서로 다른 논리를 가리 키 때문에 쿼리가 그 기반으로 작성 그것은 우리에게 큰 힘과 유연성을 제공해야합니다.

    내부는 예는 옵티마이을 확인할 수 있도록 그러나 같은 결과를 반환 가입하세요.

  4. ==============================

    4.그래서 심지어 INNER이 (가) 과정을 가입하는 동안 그들은 이미 제외 할 수 있도록 조항이 옵티 마이저에 의해 rearrranged 술어를 가질 수 WHERE와 쿼리 가입하세요, 관계형 대수는 WHERE 절에서 술어의 호환성을 허용하고 내부는 가입하세요.

    그래서 심지어 INNER이 (가) 과정을 가입하는 동안 그들은 이미 제외 할 수 있도록 조항이 옵티 마이저에 의해 rearrranged 술어를 가질 수 WHERE와 쿼리 가입하세요, 관계형 대수는 WHERE 절에서 술어의 호환성을 허용하고 내부는 가입하세요.

    난 당신이 가능한 가장 읽기 쉬운 방식으로 쿼리를 작성하는 것이 좋습니다.

    때때로 이것은 내부가 상대적으로 "불완전"가입하고 단순히 더 쉽게 유지 보수 기준을 필터링의 목록을 만들기 위해 WHERE의 기준의 일부를 퍼팅이 포함되어 있습니다.

    이 링크에서 자세한 내용을 얻을 수 있습니다 : http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause

    예를 들어, 대신 :

    SELECT *
    FROM Customers c
    INNER JOIN CustomerAccounts ca
        ON ca.CustomerID = c.CustomerID
        AND c.State = 'NY'
    INNER JOIN Accounts a
        ON ca.AccountID = a.AccountID
        AND a.Status = 1
    

    쓰다:

    SELECT *
    FROM Customers c
    INNER JOIN CustomerAccounts ca
        ON ca.CustomerID = c.CustomerID
    INNER JOIN Accounts a
        ON ca.AccountID = a.AccountID
    WHERE c.State = 'NY'
        AND a.Status = 1
    

    그러나 물론, 따라 달라집니다.

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

    5.SQL 구문에 대해 생각 할 때 SQL 작업의 논리적 순서를 이해하는 것이 중요합니다. 조인 연산자 (그리고 관련 참가할 ON이 속해) FROM 절. FROM 절은 (optimisers 여전히 재주문 가지로 선택할 수 있습니다) 논리적으로 실행하는 최초의 작업입니다.

    SQL 구문에 대해 생각 할 때 SQL 작업의 논리적 순서를 이해하는 것이 중요합니다. 조인 연산자 (그리고 관련 참가할 ON이 속해) FROM 절. FROM 절은 (optimisers 여전히 재주문 가지로 선택할 수 있습니다) 논리적으로 실행하는 최초의 작업입니다.

    당신의 예에서, 정말 차이가 아니라, 내가 블로그 게시물에서 (예를 외부 조인의 ON과 WHERE 사이의 차이에 대한이 블로그 게시물에 표시된 Sakila 데이터베이스를 사용했습니다으로는 하나를 구성하기 쉽다 ) :

    첫 번째 쿼리

    SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id)
    FROM actor a
    LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
    WHERE fa.film_id < 10
    GROUP BY a.actor_id, a.first_name, a.last_name
    ORDER BY count(fa.film_id) ASC;
    

    수익률 :

    ACTOR_ID  FIRST_NAME  LAST_NAME  COUNT
    --------------------------------------
    194       MERYL       ALLEN      1
    198       MARY        KEITEL     1
    30        SANDRA      PECK       1
    85        MINNIE      ZELLWEGER  1
    123       JULIANNE    DENCH      1
    

    우리가 WHERE 절에서 외부 조인 된 테이블을 필터링하기 때문에, LEFT 효과적으로 내부에 가입되어 있었다 JOIN. 왜? 우리가 영화에서 재생되지 않은 배우가 있다면, fa.film_id 것 그 배우의 유일한 행이 NULL이고, fa.film_id <10 술어 따라서 NULL를 얻을 것 때문에. 그러한 배우가 단지 내부와 마찬가지로, 결과에서 제외됩니다 가입하세요.

    두 번째 쿼리

    SELECT a.actor_id, a.first_name, a.last_name, count(fa.film_id)
    FROM actor a
    LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id
      AND fa.film_id < 10
    GROUP BY a.actor_id, a.first_name, a.last_name
    ORDER BY count(fa.film_id) ASC;
    

    수익률 :

    ACTOR_ID  FIRST_NAME  LAST_NAME     COUNT
    -----------------------------------------
    3         ED          CHASE         0
    4         JENNIFER    DAVIS         0
    5         JOHNNY      LOLLOBRIGIDA  0
    6         BETTE       NICHOLSON     0
    ...
    1         PENELOPE    GUINESS       1
    200       THORA       TEMPLE        1
    2         NICK        WAHLBERG      1
    198       MARY        KEITEL        1
    

    fa.film_id <10 술어가 왼쪽의 일부 술어 ON의 JOIN을하기 때문에 이제 영화가없는 배우가 결과에 포함됩니다

    결론

    그들은 논리적으로 가장 의미가 어디에 항상 술어를 배치합니다.

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

    6.1)

    1)

    SQL1: select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 **and** t1.f2=1 and t1.f3=0 
    

    이것에서는, 파서는이 3 개 개의 조건 (T2)의 각 행에 (T1)의 각 행을 검사 할 것이다. 빠른 결과를 얻기.

    2) SQL2 : 선택 t1.f1, T1로부터 t2.f2가 t1.f1 = T2 t2.f2에 가입 왼쪽 여기서 ** ** t1.f2 = 1 = 0 t1.f3

    이러한면에서, 가입 만 1 조건을 가지고, 결과는 그 두 조건을 필터링 조인에서 얻었다. 그리고 1 쿼리보다 더 많은 시간이 소요됩니다.

    http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause : 당신은이 링크에서 자세한 내용을 얻을 수 있습니다

  7. from https://stackoverflow.com/questions/8311096/whats-the-difference-between-where-clause-and-on-clause-when-table-left-join by cc-by-sa and MIT license