복붙노트

[SQL] SQL은 조인 절에 where 절 대를

SQL

SQL은 조인 절에 where 절 대를

그것을 읽은 후,이 암시 SQL 조인 대 명시의 중복이 아니다. 대답은 관련이있을 수 있습니다 (또는 동일)하지만 문제는 다르다.

무슨 차이가 각각 무엇을 가야하나요?

내가 제대로 이론을 이해한다면, 쿼리 최적화 상호 교환을 모두 사용할 수 있어야합니다.

해결법

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

    1.그들은 같은 것이 아니다.

    그들은 같은 것이 아니다.

    이러한 쿼리를 고려하십시오

    SELECT *
    FROM Orders
    LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID
    WHERE Orders.ID = 12345
    

    SELECT *
    FROM Orders
    LEFT JOIN OrderLines ON OrderLines.OrderID=Orders.ID 
        AND Orders.ID = 12345
    

    첫 번째는 주문 번호 12345 모든 주문을 반환합니다 두 번째,하지만 그와 관련된 어떤 라인을 가지고에만 위해 12345를 들어,있는 경우, 주문 및 라인을 반환합니다.

    내부 조인으로, 절 효과적으로 동등하다. 그러나, 그들은 동일한 결과를 생성한다는 점에서, 조항의 두 종류 같은 의미 론적 의미를 가지고 의미하지 않는다, 기능적으로 동일해서.

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

    2.

    예 : 테이블 아래의 고려 :

        1. documents:
         | id    | name        |
         --------|-------------|
         | 1     | Document1   |
         | 2     | Document2   |
         | 3     | Document3   |
         | 4     | Document4   |
         | 5     | Document5   |
    
    
        2. downloads:
         | id   | document_id   | username |
         |------|---------------|----------|
         | 1    | 1             | sandeep  |
         | 2    | 1             | simi     |
         | 3    | 2             | sandeep  |
         | 4    | 2             | reya     |
         | 5    | 3             | simi     |
    

    A) 내부 WHERE 절 :

      SELECT documents.name, downloads.id
        FROM documents
        LEFT OUTER JOIN downloads
          ON documents.id = downloads.document_id
        WHERE username = 'sandeep'
    
     For above query the intermediate join table will look like this.
    
        | id(from documents) | name         | id (from downloads) | document_id | username |
        |--------------------|--------------|---------------------|-------------|----------|
        | 1                  | Document1    | 1                   | 1           | sandeep  |
        | 1                  | Document1    | 2                   | 1           | simi     |
        | 2                  | Document2    | 3                   | 2           | sandeep  |
        | 2                  | Document2    | 4                   | 2           | reya     |
        | 3                  | Document3    | 5                   | 3           | simi     |
        | 4                  | Document4    | NULL                | NULL        | NULL     |
        | 5                  | Document5    | NULL                | NULL        | NULL     |
    
      After applying the `WHERE` clause and selecting the listed attributes, the result will be: 
    
       | name         | id |
       |--------------|----|
       | Document1    | 1  |
       | Document2    | 3  | 
    

    b)는 내부는 JOIN 절을

      SELECT documents.name, downloads.id
      FROM documents
        LEFT OUTER JOIN downloads
          ON documents.id = downloads.document_id
            AND username = 'sandeep'
    
    For above query the intermediate join table will look like this.
    
        | id(from documents) | name         | id (from downloads) | document_id | username |
        |--------------------|--------------|---------------------|-------------|----------|
        | 1                  | Document1    | 1                   | 1           | sandeep  |
        | 2                  | Document2    | 3                   | 2           | sandeep  |
        | 3                  | Document3    | NULL                | NULL        | NULL     |
        | 4                  | Document4    | NULL                | NULL        | NULL     |
        | 5                  | Document5    | NULL                | NULL        | NULL     |
    
    Notice how the rows in `documents` that did not match both the conditions are populated with `NULL` values.
    
    After Selecting the listed attributes, the result will be: 
    
       | name       | id   |
       |------------|------|
       |  Document1 | 1    |
       |  Document2 | 3    | 
       |  Document3 | NULL |
       |  Document4 | NULL | 
       |  Document5 | NULL | 
    
  3. ==============================

    3.내부 조인 그들은 상호 교환하고, 최적화는 의지에서 다시 정렬됩니다.

    내부 조인 그들은 상호 교환하고, 최적화는 의지에서 다시 정렬됩니다.

    OUTER 조인에서 그들이 의존 조인의 어느 측면에 따라서, 반드시 교환 가능하지 않다.

    나는 가독성에 따라 어느 장소에 넣어.

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

    4.내가 할 방법은 다음과 같습니다

    내가 할 방법은 다음과 같습니다

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

    5.내부 조인, 그들은 같은 일을 의미한다. 그러나 당신이이 대 ON 절에 조인 조건을 외부에서 다른 결과가 넣어 경우에 따라 조인 얻을 것이다. 이 관련된 질문에 대해 살펴과 (내게로)이 답을 가지고.

    내부 조인, 그들은 같은 일을 의미한다. 그러나 당신이이 대 ON 절에 조인 조건을 외부에서 다른 결과가 넣어 경우에 따라 조인 얻을 것이다. 이 관련된 질문에 대해 살펴과 (내게로)이 답을 가지고.

    나는 항상 퍼팅의 습관으로 가장 적합한 생각이 쿼리를 읽는 사람에게 명확하게로 (그것이하지 않는 한 외부에 가입하고 당신이 실제로 할 WHERE 절에 원하는) ON 절에 조인 조건 어떤 조건 테이블에 결합되고, 또한 그것은 긴 줄 ​​수십되는 것을 WHERE 절을 방지하는 데 도움이됩니다.

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

    6.이 문서에서는 명확하게 차이를 설명합니다. 또한 "joined_condition 또는 joined_alias가 null WHERE 대 ON의 joined_condition"을 설명합니다.

    이 문서에서는 명확하게 차이를 설명합니다. 또한 "joined_condition 또는 joined_alias가 null WHERE 대 ON의 joined_condition"을 설명합니다.

    절 결과를 필터링 WHERE 절 FROM ON 절로부터 상기 테이블 조인 테이블의 결과를 생성하기 위해 사용되는 동안 조인과 함께.

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

    7.그것은 왼쪽 가입 때 절에 where 절 대 사이에 큰 차이가있다.

    그것은 왼쪽 가입 때 절에 where 절 대 사이에 큰 차이가있다.

    다음은 예입니다 :

    mysql> desc t1; 
    +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | id    | int(11)     | NO   |     | NULL    |       |
    | fid   | int(11)     | NO   |     | NULL    |       |
    | v     | varchar(20) | NO   |     | NULL    |       |
    +-------+-------------+------+-----+---------+-------+
    

    버팀대 테이블 T2의 ID가 있습니다.

    mysql> desc t2;
    +-------+-------------+------+-----+---------+-------+
    | Field | Type        | Null | Key | Default | Extra |
    +-------+-------------+------+-----+---------+-------+
    | id    | int(11)     | NO   |     | NULL    |       |
    | v     | varchar(10) | NO   |     | NULL    |       |
    +-------+-------------+------+-----+---------+-------+
    2 rows in set (0.00 sec)
    

    "절에"에 대한 쿼리 :

    mysql> SELECT * FROM `t1` left join t2 on fid = t2.id AND t1.v = 'K' 
        -> ;
    +----+-----+---+------+------+
    | id | fid | v | id   | v    |
    +----+-----+---+------+------+
    |  1 |   1 | H | NULL | NULL |
    |  2 |   1 | B | NULL | NULL |
    |  3 |   2 | H | NULL | NULL |
    |  4 |   7 | K | NULL | NULL |
    |  5 |   5 | L | NULL | NULL |
    +----+-----+---+------+------+
    5 rows in set (0.00 sec)
    

    "where 절"에 대한 쿼리 :

    mysql> SELECT * FROM `t1` left join t2 on fid = t2.id where t1.v = 'K';
    +----+-----+---+------+------+
    | id | fid | v | id   | v    |
    +----+-----+---+------+------+
    |  4 |   7 | K | NULL | NULL |
    +----+-----+---+------+------+
    1 row in set (0.00 sec)
    

    그것은 그것을 분명하다, 첫 번째 쿼리는 T1에서 기록 및 행 t1.v = 'K'에 대한 T2에서 종속 행이있는 경우, 반환합니다.

    T1에서,하지만 t1.v = 'K'의 두 번째 쿼리 반환 행은 그와 연관된 행이됩니다.

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

    8.당신이 당신의 위치에 또는 함께 절을 조인을 정의 여부를 최적화의 관점에서, 그것은 변화를하지 않아야합니다.

    당신이 당신의 위치에 또는 함께 절을 조인을 정의 여부를 최적화의 관점에서, 그것은 변화를하지 않아야합니다.

    그러나, IMHO, 나는 그것을 조인 수행 할 때 ON 절을 사용하는 것이 훨씬 명확하게 생각합니다. 당신이 당신의 특정 부분을 그런 식으로는 WHERE 조항의 나머지 부분과 혼합 대 취급 조인 어떻게 지시를 쿼리합니다.

  9. ==============================

    9.하자 그 테이블을 고려 :

    하자 그 테이블을 고려 :

    id | SomeData
    

    id | id_A | SomeOtherData
    

    ID_A는 테이블 A에 대한 외래 키 인

    이 쿼리를 작성 :

    SELECT *
    FROM A
    LEFT JOIN B
    ON A.id = B.id_A;
    

    이 결과를 제공 할 것입니다 :

    / : part of the result
                                           B
                          +---------------------------------+
                A         |                                 |
    +---------------------+-------+                         |
    |/////////////////////|///////|                         |
    |/////////////////////|///////|                         |
    |/////////////////////|///////|                         |
    |/////////////////////|///////|                         |
    |/////////////////////+-------+-------------------------+
    |/////////////////////////////|
    +-----------------------------+
    

    (A)에 무엇인가가 아니라 B ​​B. 수단에 대한 NULL 값이 있다는

    자,하자가 B.id_A의 특정 부분을 고려하고, 이전 결과에서 강조 표시 :

    / : part of the result
    * : part of the result with the specific B.id_A
                                           B
                          +---------------------------------+
                A         |                                 |
    +---------------------+-------+                         |
    |/////////////////////|///////|                         |
    |/////////////////////|///////|                         |
    |/////////////////////+---+///|                         |
    |/////////////////////|***|///|                         |
    |/////////////////////+---+---+-------------------------+
    |/////////////////////////////|
    +-----------------------------+
    

    이 쿼리를 작성 :

    SELECT *
    FROM A
    LEFT JOIN B
    ON A.id = B.id_A
    AND B.id_A = SpecificPart;
    

    이 결과를 제공 할 것입니다 :

    / : part of the result
    * : part of the result with the specific B.id_A
                                           B
                          +---------------------------------+
                A         |                                 |
    +---------------------+-------+                         |
    |/////////////////////|       |                         |
    |/////////////////////|       |                         |
    |/////////////////////+---+   |                         |
    |/////////////////////|***|   |                         |
    |/////////////////////+---+---+-------------------------+
    |/////////////////////////////|
    +-----------------------------+
    

    내측이들을 제거 B.id_A = SpecificPart가 아닌 값을 가입 때문에

    지금,이에 쿼리를 변경할 수 있습니다 :

    SELECT *
    FROM A
    LEFT JOIN B
    ON A.id = B.id_A
    WHERE B.id_A = SpecificPart;
    

    그 결과는 지금 :

    / : part of the result
    * : part of the result with the specific B.id_A
                                           B
                          +---------------------------------+
                A         |                                 |
    +---------------------+-------+                         |
    |                     |       |                         |
    |                     |       |                         |
    |                     +---+   |                         |
    |                     |***|   |                         |
    |                     +---+---+-------------------------+
    |                             |
    +-----------------------------+
    

    전체적인 결과는 B로하지 않는 (A)에있는 부분 B.id_A = NULL을 제거 B.id_A = SpecificPart 대해 필터링되므로

  10. ==============================

    10.당신은 데이터 또는 필터 데이터를 결합하려고합니까?

    당신은 데이터 또는 필터 데이터를 결합하려고합니까?

    가독성을 위해 그것은 각각 ON과 WHERE 이러한 사용 사례를 분리하는 것이 가장 바람직합니다.

    그것은 WHERE 절에 조건을 가입 쿼리와 필터링 조건의 존재를 읽고 매우 어려워 질 수 있습니다.

    그것은 가치가 \ ¯ 시도 할 수 있도록 SQL의 다른 유형은 때때로 다른 쿼리 계획을 처리하지만 성능이 현명한 당신이 _ / ¯ (ツ) _, 차이를 볼 수 없습니다해야한다 (마 쿼리 속도를 초래 캐시의 인식)

    다른 사람이 언급 한 또한 당신이 외부를 사용하는 경우, 당신은 ON 절에 필터 조건을 배치하면 서로 다른 결과를 얻을 조인 테이블의 그것은 단지 효과 하나 때문에.

    나는 여기에 대해 깊이 게시물에 더 썼다 : https://dataschool.com/learn/difference-between-where-and-on-in-sql

  11. ==============================

    11.SQL에서 ''와 'ON'절은, 일종의 조건부 Statemants의, 그러나 그들 사이의 가장 큰 차이점은 'ON'절, 반면 '어디'절은 조건을 지정하기위한 선택 / 업데이트 문에 사용되는입니다 이 검증 또는 검사 위치를 기록 대상 및 소스 테이블에 일치하는 경우, 테이블을 접합하기 전에, 합류에서 사용

    SQL에서 ''와 'ON'절은, 일종의 조건부 Statemants의, 그러나 그들 사이의 가장 큰 차이점은 'ON'절, 반면 '어디'절은 조건을 지정하기위한 선택 / 업데이트 문에 사용되는입니다 이 검증 또는 검사 위치를 기록 대상 및 소스 테이블에 일치하는 경우, 테이블을 접합하기 전에, 합류에서 사용

    예를 들면 : - 'WHERE'

    SELECT * FROM employee WHERE employee_id=101
    

    예를 들면 : - 'ON'

    두 테이블의 직원 및 employee_details이있다, 일치하는 열은 employee_id입니다이다.

    SELECT * FROM employee 
    INNER JOIN employee_details 
    ON employee.employee_id = employee_details.employee_id
    

    희망 나는 당신의 질문에 대답했다. 어떤 해명 되돌립니다.

  12. ==============================

    12.나는 그것이 순서 효과에 가입 같아요. 왼쪽 상단에 가입 경우, SQL은 왼쪽 처음 가입 할 다음 경우 필터를 않습니다. 다우 너 경우, 가입 않습니다 먼저 Orders.ID = 12345을 발견하고.

    나는 그것이 순서 효과에 가입 같아요. 왼쪽 상단에 가입 경우, SQL은 왼쪽 처음 가입 할 다음 경우 필터를 않습니다. 다우 너 경우, 가입 않습니다 먼저 Orders.ID = 12345을 발견하고.

  13. ==============================

    13.내부 조인의 경우, ON은 상호 교환 사용할 수 있습니다 WHERE합니다. 사실, 그것은 상관 하위 쿼리에 ON 사용 가능합니다. 예를 들면 :

    내부 조인의 경우, ON은 상호 교환 사용할 수 있습니다 WHERE합니다. 사실, 그것은 상관 하위 쿼리에 ON 사용 가능합니다. 예를 들면 :

    update mytable
    set myscore=100
    where exists (
    select 1 from table1
    inner join table2
    on (table2.key = mytable.key)
    inner join table3
    on (table3.key = table2.key and table3.key = table1.key)
    ...
    )
    

    이것은 (IMHO)가 완전히 인간에 혼란이며, ( "드라이버"테이블이 조항 "의"가 없기 때문에) 아무것도 링크 표에 잊지 매우 쉽지만, 그것은 법적이다.

  14. ==============================

    14.더 나은 성능 테이블 조인에 사용하는 특별한 인덱스 컬럼을 가지고 있어야합니다.

    더 나은 성능 테이블 조인에 사용하는 특별한 인덱스 컬럼을 가지고 있어야합니다.

    당신의 조건 열이 다음 해당 인덱스 열 중 하나가 아닌 경우 그래서는 WHERE에 보관하는 것이 좋습니다 생각한다.

    당신이 인덱스 컬럼을 사용하여 가입, 그래서 다음 시간 이후에 당신이 없음 인덱스 컬럼에 대한 조건을 실행 가입하세요.

  15. ==============================

    15.두 테이블이 이미 가입 한 후에는 일반적으로 필터링은 WHERE 절에서 처리됩니다. 당신이 그들을 결합하기 전에 필터 하나 또는 테이블에 모두 할 수 있습니다이 있지만 그것은 가능합니다. (가) 문제의 참여에 절에 만 적용하는 반면 즉은, where 절은 전체 결과 집합에 적용됩니다.

    두 테이블이 이미 가입 한 후에는 일반적으로 필터링은 WHERE 절에서 처리됩니다. 당신이 그들을 결합하기 전에 필터 하나 또는 테이블에 모두 할 수 있습니다이 있지만 그것은 가능합니다. (가) 문제의 참여에 절에 만 적용하는 반면 즉은, where 절은 전체 결과 집합에 적용됩니다.

  16. ==============================

    16.나는이 차이가 가장 단순화이다 SQL에서 작업의 논리적 순서를 통해 설명 될 수 있다고 생각합니다 :

    나는이 차이가 가장 단순화이다 SQL에서 작업의 논리적 순서를 통해 설명 될 수 있다고 생각합니다 :

    조인은 select 문의 절,하지만 FROM의 운영자 내부 없습니다. 이와 같이, 대응 속하는 모든 ON 절 연산자는 "이미 일어난"가입 한 논리적 때에는 논리 처리는 WHERE 절에 도달한다. 좌측의 경우는 가입이 수단은, 예를 들면, 외측 이미 WHERE 절인가 시간에 의해 생긴있다의 의미를 조인.

    나는이 블로그 게시물에 깊이 더 다음의 예를 설명했습니다. 이 쿼리를 실행하는 경우 :

    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 film_id < 10
    GROUP BY a.actor_id, a.first_name, a.last_name
    ORDER BY count(fa.film_id) ASC;
    

    왼쪽은 배우가 영화에서 재생되지 않은 경우에도 배우가 그 FILM_ID는 NULL이 될 것 같은, 여과되기 때문에 정말 유용한 효과가없는 가입 절은 행을 필터링 할 곳. 결과는 같은 것입니다 :

    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
    

    즉 것처럼 우리는 내부 두 테이블에 합류했다. 우리는 ON 절에 필터 조건을 이동하면, 지금은 외부에 대한 기준이 결합된다 :

    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 film_id < 10
    GROUP BY a.actor_id, a.first_name, a.last_name
    ORDER BY count(fa.film_id) ASC;
    

    결과를 의미하는 <10 어떤 영화 배우를 포함하지 않고 또는 어떤 필름 FILM_ID없는 것

    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
    

    그것은 가장 적합한 위치를 항상 논리적으로, 당신의 술어를 넣어.

  17. ==============================

    17.귀하의 질문에 대해서는,

    귀하의 질문에 대해서는,

    그것은 모두 '에'동일 또는 '어디에'내부만큼 서버가 그것을 얻을 수있는 가입에 :

    select * from a inner join b on a.c = b.c
    

    select * from a inner join b where a.c = b.c
    

    '어디'옵션은 모든 통역사는 어쩌면 피해야한다 알고 있지. 그리고 물론 '에'절은 명확하다.

  18. ==============================

    18.이 내 솔루션입니다.

    이 내 솔루션입니다.

    SELECT song_ID,songs.fullname, singers.fullname
    FROM music JOIN songs ON songs.ID = music.song_ID  
    JOIN singers ON singers.ID = music.singer_ID
    GROUP BY songs.fullname
    

    당신은 일에 얻을 수있는 그룹 BY 있어야합니다.

    이 도움을 바랍니다.

  19. from https://stackoverflow.com/questions/354070/sql-join-where-clause-vs-on-clause by cc-by-sa and MIT license