복붙노트

[SQL] SQL은 행에서 여러 테이블 대에 가입 왼쪽?

SQL

SQL은 행에서 여러 테이블 대에 가입 왼쪽?

대부분의 SQL 언어는 모두 다음과 같은 쿼리를 받아 :

SELECT a.foo, b.foo
FROM a, b
WHERE a.x = b.x

SELECT a.foo, b.foo
FROM a
LEFT JOIN b ON a.x = b.x

당신이 외부 조인을 필요로 할 때 지금은 분명, 두 번째 구문이 필요합니다. 하지만 (반대 또는 그) 처음에 두 번째 구문을 선호해야하는 이유 내부 조인 할 때?

해결법

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

    1.단지 테이블을 나열하고,이 기준에 합류 지정하는 WHERE 절을 사용하여 함께 이전 구문은, 가장 현대적인 데이터베이스에 사용되지 않습니다.

    단지 테이블을 나열하고,이 기준에 합류 지정하는 WHERE 절을 사용하여 함께 이전 구문은, 가장 현대적인 데이터베이스에 사용되지 않습니다.

    그것은 이전 구문 당신은 내부와 외부 모두 동일한 쿼리에서 조인을 사용하는 경우 모호한 존재의 가능성이, 단지 쇼를 위해 아닙니다.

    한 가지 예를 들어 보겠습니다.

    의 당신이 당신의 시스템의 3 개 테이블이 있다고 가정하자 :

    Company
    Department
    Employee
    

    각 테이블은 서로 연결된 다수의 행을 포함합니다. 여러 회사를 가지고, 각 회사는 여러 부서를 가질 수 있으며 각 부서의 여러 직원이있을 수 있습니다.

    자, 이제 당신은 다음을 수행 할 :

    당신은이 작업을 수행 할 수 있도록 :

    SELECT * -- for simplicity
    FROM Company, Department, Employee
    WHERE Company.ID *= Department.CompanyID
      AND Department.ID = Employee.DepartmentID
    

    당신은 단지 사람과 부서를 원하는 기준을 충족하기 위해, 내부 조인이 마지막합니다.

    자, 이제 어떻게 그래서 뭐. 음, 문제는, 데이터베이스 엔진, 쿼리 최적화, 인덱스 및 테이블 통계에 따라 달라집니다. 설명해 드리죠.

    쿼리 최적화 프로그램이 작업을 수행하는 방법은 먼저, 회사를 가지고 부서를 찾은 다음 내부 직원에 가입 할 것을 결정하면, 당신은 부서가없는 모든 회사를 얻을하지 않을거야.

    그 이유는 WHERE 절 행이 최종 결과의 행 개별없는 부분 끝을 결정한다는 것이다.

    그리고 가입 왼쪽으로 인해,이 경우는 Department.ID 열은 NULL이됩니다, 그것은 내부에 관해서 따라서 직원에 가입, 거기 직원 행에 대한 그 제약 조건을 충족 할 수있는 방법은 없습니다, 그리고 그것은하지 않습니다 나타나다.

    한편, 쿼리 최적화 프로그램은 부서 직원이 처음에 가입 해결하고 회사와, 당신이 그들을 볼 조인 왼쪽을하기로 결정합니다.

    따라서 이전 구문이 모호합니다. 이 쿼리 힌트를 처리하지 않고, 당신이 원하는 것을 지정할 수있는 방법은 없습니다, 일부 데이터베이스는 전혀 방법이 없습니다.

    이 당신이 선택할 수 있습니다, 새로운 구문을 입력합니다.

    모든 회사를 원하는 경우 예를 들어, 언급 된 문제 설명으로, 이것은 당신이 쓸 것 인 것이다 :

    SELECT *
    FROM Company
         LEFT JOIN (
             Department INNER JOIN Employee ON Department.ID = Employee.DepartmentID
         ) ON Company.ID = Department.CompanyID
    

    여기에 당신은 당신이 부서 직원이 하나의 조인으로 수행되어야 가입 한 다음 왼쪽 회사와 그 결과에 가입 할 것을 지정합니다.

    또한, 이제 당신은 단지 이름에 문자 X를 포함 부서를 원하는 가정 해 봅시다. 다시 이전 스타일 조인과 함께, 당신은 그것의 이름에 X 어떤 부서가없는 경우뿐만 아니라, 회사를 잃을 위험이 있지만, 새로운 구문, 당신은이 작업을 수행 할 수 있습니다 :

    SELECT *
    FROM Company
         LEFT JOIN (
             Department INNER JOIN Employee ON Department.ID = Employee.DepartmentID
         ) ON Company.ID = Department.CompanyID AND Department.Name LIKE '%X%'
    

    이 추가 절은 결합에 사용하지만, 전체 행에 대한 필터 아닙니다. 행이 회사의 정보와 함께 표시 될 수 있지만 회사의 이름에 X 아무 부서가 없기 때문에, 해당 행에 대한 모든 부서 및 직원 열에서 null을 가질 수 있도록. 이것은 오래된 구문 어렵다.

    다른 공급 업체 사이에, SQL Server 2005 및 위쪽으로하기 때문에, 마이크로 소프트는 기존의 외부 조인 구문을 사용되지 않았지만 기존의 내부하지 구문을 가입하는 이유입니다. 유일한 방법은 조인 구문을 오래된 스타일의 외부를 사용하여, 마이크로 소프트 SQL 서버 2005 또는 2008에서 실행되는 데이터베이스에 얘기, (SQL Server 2000의 일명) 8.0 호환 모드에서 해당 데이터베이스를 설정하는 것입니다.

    또한, 기존의 방법은, WHERE 절 무리와 함께, 쿼리 최적화 프로그램에서 테이블의 무리를 던져, "여기에 당신이, 당신이 할 수있는 최선을"말과 비슷했다. 새로운 구문으로, 쿼리 최적화 프로그램은 부품이 함께 어떤 일이 일어나는지 파악하기 위해 할 수있는 작은 일이있다.

    그래서 당신은 그것을이 있습니다.

    왼쪽 및 INNER는 미래의 물결입니다 가입.

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

    2.구문들이 적용 테이블에 가까운 상태를 유지 가입하세요. 당신이 테이블의 많은 양에 가입 할 때 특히 유용합니다.

    구문들이 적용 테이블에 가까운 상태를 유지 가입하세요. 당신이 테이블의 많은 양에 가입 할 때 특히 유용합니다.

    그건 그렇고, 당신은 할 수있는 외부도 첫 번째 구문을 사용하여 조인

    WHERE a.x = b.x(+)
    

    또는

    WHERE a.x *= b.x
    

    또는

    WHERE a.x = b.x or a.x not in (select x from b)
    
  3. ==============================

    3.첫 번째 방법은 기존의 표준입니다. 두 번째 방법은 SQL-92 http://en.wikipedia.org/wiki/SQL에 도입 하였다. 전체 표준은 http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt에서 볼 수 있습니다.

    첫 번째 방법은 기존의 표준입니다. 두 번째 방법은 SQL-92 http://en.wikipedia.org/wiki/SQL에 도입 하였다. 전체 표준은 http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt에서 볼 수 있습니다.

    데이터베이스 회사는 SQL-92 표준을 채택하기 전에 많은 년이 걸렸다.

    두 번째 방법을 선호하는 이유 그래서, 그것은 ANSI와 ISO 표준위원회를 따라 SQL 표준입니다.

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

    4.기본적으로, 때를 절 목록에서 테이블과 같이 :

    기본적으로, 때를 절 목록에서 테이블과 같이 :

    SELECT * FROM
      tableA, tableB, tableC
    

    결과는 A, B는 C를 그런 다음 제한을 적용 테이블의 행 모두의 크로스 제품입니다 WHERE tableA.id = tableB.a_id 행 다음에, 또 ... AND tableB.id의 거대한 수를 버릴 것이다 = tableC.b_id 당신은 당신이 정말로에 관심이 있습니다 만 행을 얻어야한다.

    DBMS를이 JOIN을 사용하여 작성하는 성능 차이는 (있는 경우)를 무시할 수 있도록이 SQL을 최적화하는 방법을 알고있다. (가) 표기를 가입 사용 (IMHO는 사용하지 엉망으로 문을 전환 조인) SQL 문을 더 읽을 수 있습니다. 십자가 제품을 사용하면 WHERE 절에 조건을 결합 제공해야하고, 표기의 문제의 그. 당신은 물건처럼 사용하여 WHERE 절을 군집하고 있습니다

        tableA.id = tableB.a_id 
    AND tableB.id = tableC.b_id 
    

    이는 단지 외적을 제한하는 데 사용됩니다. WHERE 절은 결과 집합에 제한을 포함해야합니다. 이 표는 결과 집합 제한 기준을 가입 혼합하는 경우 (및 기타) 쿼리 열심히 읽기가 있습니다. 당신은 확실히 사용 조인해야하고 FROM 절 절 a로부터 유지하고 WHERE 절 WHERE 절.

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

    5.그 결과 훨씬 적은 가능성이 있기 때문에 두 번째는 우발적 인 크로스 바람직하다는 where 절을 기계가 넣어 잊고으로 가입 할 수 있습니다. 절은 실패하지 않습니다 경우 A는 문법 체크를 실패 절에는 함께 참여하지, 이전 스타일이 더에 참여하지, 그것은 십자가에 가입 할 것입니다.

    그 결과 훨씬 적은 가능성이 있기 때문에 두 번째는 우발적 인 크로스 바람직하다는 where 절을 기계가 넣어 잊고으로 가입 할 수 있습니다. 절은 실패하지 않습니다 경우 A는 문법 체크를 실패 절에는 함께 참여하지, 이전 스타일이 더에 참여하지, 그것은 십자가에 가입 할 것입니다.

    가입 나중에 왼쪽에있을 때 또한, 그들이 모두 같은 구조로하는 것이 유지 보수를 위해 도움이됩니다. 그리고 이전 구문은 사용을 중지 할 아니라 과거의 시간, 1992 년부터 유효 기간이 경과되었습니다.

    게다가 나는 독점적으로 정말 이해가되지 않는 첫 번째 구문을 사용하는 많은 사람들이 참여와 이해가 쿼리 할 때 올바른 결과를 얻는 데 중요 조인 것으로 나타났습니다.

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

    6.나는 명시 적 조인 - 특수 두 번째 방법을 채택하는이 페이지에 좋은 이유가 있다고 생각합니다. 클린 처하지만은 WHERE 절에 남아있는 선택 기준을 참조하기가 훨씬 쉬워집니다 조인 조건은 WHERE 절에서 제거하는 것입니다.

    나는 명시 적 조인 - 특수 두 번째 방법을 채택하는이 페이지에 좋은 이유가 있다고 생각합니다. 클린 처하지만은 WHERE 절에 남아있는 선택 기준을 참조하기가 훨씬 쉬워집니다 조인 조건은 WHERE 절에서 제거하는 것입니다.

    정말 복잡한 SELECT 문에서 그것은 독자가 무슨 일이 일어나고 있는지 이해하기 훨씬 쉬워집니다.

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

    7.표 1, 표 2에서 SELECT *는 ... 구문은 테이블의 몇 가지에 대한 확인이지만 테이블의 수가 증가함에 따라 읽기 힘들어 (반드시 수학적으로 정확한 문장) 기하 급수적으로된다.

    표 1, 표 2에서 SELECT *는 ... 구문은 테이블의 몇 가지에 대한 확인이지만 테이블의 수가 증가함에 따라 읽기 힘들어 (반드시 수학적으로 정확한 문장) 기하 급수적으로된다.

    는 구문 (처음에) 더 열심히 작성하는 것입니다 가입하지만, 어느 테이블에 영향을 미치는 어떤 기준이 명시한다. 이것은 더 힘들어 실수를 할 수 있습니다.

    모든 조인 경우에도 INNER는 두 버전은 동일입니다. 그러나, 당신은 OUTER이 순간은 아무 곳이나 문에, 상황이 훨씬 더 복잡하고 실제로 당신이 쓰는 당신이 당신이 쓴 무슨 생각을 조회되지 않는다는 것을 보장 할 것 가입 할 수 있습니다.

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

    8.당신이 외부를 필요로 할 때 두 번째 구문은 항상 필요하지 않습니다 조인

    당신이 외부를 필요로 할 때 두 번째 구문은 항상 필요하지 않습니다 조인

    신탁:

    SELECT a.foo, b.foo
      FROM a, b
     WHERE a.x = b.x(+)
    

    에서 MSSQLServer (이 2000 버전에서 사용되지 비록) /베이스 :

    SELECT a.foo, b.foo
      FROM a, b
     WHERE a.x *= b.x
    

    그러나 귀하의 질문에 반환. 가입 : 나는 당신이 정확히하고있는 where 절에 표현식을 추가하는 대신 답을 알고하지 않습니다, 그러나 그것은 아마이 (적어도, 구문) 자연 조인 사실과 관련이 있습니다.

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

    9.나는 많은 사람들이 첫 번째는 이해하기가 너무 어렵고 불분명 불평을 듣는다. 나는 그것으로 문제가 표시되지 않습니다,하지만 토론을 한 후, 난 INNER에 두 번째는 명확성을 위해 JOINS 사용합니다.

    나는 많은 사람들이 첫 번째는 이해하기가 너무 어렵고 불분명 불평을 듣는다. 나는 그것으로 문제가 표시되지 않습니다,하지만 토론을 한 후, 난 INNER에 두 번째는 명확성을 위해 JOINS 사용합니다.

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

    10.데이터베이스에, 그들은 같은 끝나게. 당신을 위해,하지만 당신은 어떤 상황에서 그 두 번째 구문을 사용해야합니다. 끝을 사용하는 데 달려 있음을 쿼리 편집을 위해, 그리고 일관성을 위해, 나는 단지 2 방식에 패턴을 거라고 (당신이 왼쪽을 필요로 알아내는 당신이 바로 가입 한 경우 가입). 그것은 독서 쿼리를 쉽게 만들 수 있습니다.

    데이터베이스에, 그들은 같은 끝나게. 당신을 위해,하지만 당신은 어떤 상황에서 그 두 번째 구문을 사용해야합니다. 끝을 사용하는 데 달려 있음을 쿼리 편집을 위해, 그리고 일관성을 위해, 나는 단지 2 방식에 패턴을 거라고 (당신이 왼쪽을 필요로 알아내는 당신이 바로 가입 한 경우 가입). 그것은 독서 쿼리를 쉽게 만들 수 있습니다.

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

    11.LEFT 조인 오른쪽 테이블에 대응하는 레코드가없는 경우에도, 제 테이블의 모든 레코드를 포함하고 있기 때문에 좋고, 제 1 및 제 2 질의는 서로 다른 결과를 얻을 수있다.

    LEFT 조인 오른쪽 테이블에 대응하는 레코드가없는 경우에도, 제 테이블의 모든 레코드를 포함하고 있기 때문에 좋고, 제 1 및 제 2 질의는 서로 다른 결과를 얻을 수있다.

  12. from https://stackoverflow.com/questions/894490/sql-left-join-vs-multiple-tables-on-from-line by cc-by-sa and MIT license