서브 쿼리 (SQL Server)

  • 2018 년 2 월 18 일
  • 읽는 데 21 분
    • W
    • M
    • T
    • M
    • j
    • +3

적용 대상 : SQL Server (지원되는 모든 버전) Azure SQL 데이터베이스 Azure SQL 관리 형 인스턴스 Azure Synapse Analytics 병렬 데이터웨어 하우스

하위 쿼리는 SELECT, INSERT 내에 중첩 된 쿼리입니다. div>, UPDATE 또는 DELETE 문 또는 다른 하위 쿼리 내부. 표현식이 허용되는 모든 곳에서 하위 쿼리를 사용할 수 있습니다. 이 예에서 하위 쿼리는 SELECT 문에서 MaxUnitPrice라는 열 식으로 사용됩니다.

하위 쿼리 기본 사항

또한 하위 쿼리는 내부 쿼리 또는 내부 선택이라고하는 반면 하위 쿼리가 포함 된 문은 외부 쿼리 또는 외부 선택이라고도합니다.

하위 쿼리를 포함하는 많은 Transact-SQL 문을 조인으로 대신 공식화 할 수 있습니다. 다른 질문은 하위 쿼리로만 제기 할 수 있습니다. Transact-SQL에서는 일반적으로 하위 쿼리를 포함하는 문과 그렇지 않은 의미 상 동등한 버전간에 성능 차이가 없습니다. 그러나 존재를 확인해야하는 경우에는 조인이 더 나은 성능을 제공합니다. 그렇지 않으면 중복을 제거하기 위해 외부 쿼리의 각 결과에 대해 중첩 된 쿼리를 처리해야합니다. 이러한 경우 조인 방식이 더 나은 결과를 제공합니다. 다음은 동일한 결과 집합을 반환하는 하위 쿼리 SELECT 및 조인 SELECT을 모두 보여주는 예입니다.

외부 SELECT 문에 중첩 된 하위 쿼리에는 다음 구성 요소가 있습니다.

  • 일반 SELECT 쿼리 일반 선택 목록 구성 요소 포함.
  • 하나 이상의 테이블 또는 뷰 이름을 포함하는 일반 FROM
  • 선택적인 WHERE 조항.
  • 선택적인 GROUP BY 조항.
  • 선택적인 HAVING 절.

하위 쿼리의 SELECT 쿼리는 항상 괄호로 묶여 있습니다. COMPUTE 또는 FOR BROWSE 절을 포함 할 수 없으며 다음과 같은 경우 ORDER BY 절만 포함 할 수 있습니다. TOP 절도 지정됩니다.

하위 쿼리는 외부의 WHERE 또는 HAVING 절 내에 중첩 될 수 있습니다. SELECT, INSERT, UPDATE 또는 DELETE 문 또는 다른 하위 쿼리 내부. 최대 32 수준의 중첩이 가능하지만 제한은 사용 가능한 메모리와 쿼리에있는 다른 식의 복잡성에 따라 달라집니다. 개별 쿼리는 최대 32 개 수준의 중첩을 지원하지 않을 수 있습니다. 하위 쿼리는 단일 값을 반환하는 경우 표현식을 사용할 수있는 모든 위치에 나타날 수 있습니다.

테이블이 외부 쿼리가 아닌 하위 쿼리에만 나타나는 경우 해당 테이블의 열은 출력 (외부 쿼리의 선택 목록)

하위 쿼리를 포함하는 문은 일반적으로 다음 형식 중 하나를 사용합니다.

  • WHERE expression IN (subquery)
  • WHERE expression comparison_operator (subquery)
  • WHERE EXISTS (하위 쿼리)

일부 Transact-SQL 문에서 하위 쿼리는 독립적 인 것처럼 평가 될 수 있습니다. 질문. 개념적으로 하위 쿼리 결과는 외부 쿼리로 대체됩니다 (이는 SQL Server가 실제로 하위 쿼리가있는 Transact-SQL 문을 처리하는 방법이 아닐 수도 있음).

세 가지 기본 유형의 하위 쿼리가 있습니다. 해당 항목 :

  • IN로 도입 된 목록 또는 ANY 또는 ALL.
  • 수정되지 않은 비교 연산자로 도입되었으며 단일 값을 반환해야합니다.

.

하위 쿼리 규칙

하위 쿼리에는 다음 제한이 적용됩니다.

  • 비교 연산자로 도입 된 하위 쿼리의 선택 목록에는 하나의 표현식 또는 열 이름 만 포함될 수 있습니다 (EXISTSINSELECT * 또는 목록).
  • 외부 쿼리의 WHERE 절에 열 이름이 포함 된 경우 하위 쿼리 선택 목록의 열과 조인 호환 가능해야합니다.
  • ntext, text 및 image 데이터 유형은 하위 쿼리 선택 목록에서 사용할 수 없습니다.
  • 단일 값을 반환해야하기 때문에 수정되지 않은 비교 연산자 (하나 키워드 ANY 또는 ALL이 뒤 따르지 않음)은 GROUP BYHAVING 절을 포함 할 수 없습니다.
  • DISTINCT 키워드는 GROUP BY를 포함하는 하위 쿼리와 함께 사용할 수 없습니다.
  • COMPUTEINTO 절은 지정할 수 없습니다.
  • ORDER BYTOP도 지정된 경우에만 지정할 수 있습니다.
  • 하위 쿼리를 사용하여 만든보기는 업데이트 할 수 없습니다.
  • EXISTS로 도입 된 하위 쿼리의 선택 목록에는 관례 적으로 별표 ( *) 단일 열 이름 대신. EXISTS로 도입 된 하위 쿼리의 규칙은 EXISTS로 도입 된 하위 쿼리가 존재를 생성하기 때문에 표준 선택 목록의 규칙과 동일합니다. 테스트하고 데이터 대신 TRUE 또는 FALSE를 반환합니다.

하위 쿼리의 열 이름 한정

다음 예에서 절은 외부 쿼리 FROM 절 (Sales.Store)의 테이블 이름에 의해 암시 적으로 규정됩니다. 하위 쿼리의 선택 목록에서 CustomerID에 대한 참조는 하위 쿼리 FROM 절, 즉 Sales.Customer 테이블에 의해 한정됩니다.

일반적인 규칙은 명령문의 열 이름이 동일한 수준의 FROM 절에 참조 된 테이블에 의해 암시 적으로 규정된다는 것입니다. 하위 쿼리의 FROM 절에 참조 된 테이블에 열이 없으면 FROM 외부 쿼리의 절입니다.

다음은 이러한 암시 적 가정이 지정된 쿼리의 모습입니다.

그것은 결코 잘못된 것이 아닙니다. 테이블 이름을 명시 적으로 명시하고 명시 적 제한이있는 테이블 이름에 대한 암시 적 가정을 항상 재정의 할 수 있습니다.

중요

열이 하위 쿼리에서 참조되는 경우 하위 쿼리의 FROM 절에서 참조하는 테이블에는 없지만 외부 쿼리의 FROM에서 참조하는 테이블에는 존재합니다. 절에서 쿼리가 오류없이 실행됩니다. SQL Server는 외부 쿼리의 테이블 이름을 사용하여 하위 쿼리의 열을 암시 적으로 한정합니다.

여러 수준의 중첩

하위 쿼리 자체에 하나 이상의 하위 쿼리가 포함될 수 있습니다. 명령문에는 여러 하위 쿼리를 중첩 할 수 있습니다.

다음 쿼리는 영업 사원이기도 한 직원의 이름을 찾습니다.

다음은 결과 집합입니다.

가장 안쪽 쿼리는 영업 사원 ID를 반환합니다. 다음 상위 수준의 쿼리는 이러한 영업 사원 ID로 평가되고 직원의 연락처 ID 번호를 반환합니다. 마지막으로 외부 쿼리는 연락처 ID를 사용하여 직원의 이름을 찾습니다.

이 쿼리를 조인으로 표현할 수도 있습니다.

서브 쿼리를 한 번 실행하고 결과 값을 외부 쿼리의 WHERE 절로 대체하여 많은 쿼리를 평가할 수 있습니다. 상관 하위 쿼리 (반복 하위 쿼리라고도 함)를 포함하는 쿼리에서 하위 쿼리는 해당 값에 대한 외부 쿼리에 의존합니다. 이는 하위 쿼리가 외부 쿼리에 의해 선택 될 수있는 각 행에 대해 한 번씩 반복적으로 실행됨을 의미합니다.이 쿼리는 SalesPerson 테이블의 보너스가 5000 인 각 직원의 이름과 성의 인스턴스 하나를 검색합니다. 직원 식별 번호는 Employee 및 SalesPerson 테이블에서 일치합니다.

결과 집합은 다음과 같습니다.

이 문의 이전 하위 쿼리는 외부 쿼리와 독립적으로 평가할 수 없습니다. Employee.BusinessEntityID에 대한 값이 필요하지만 SQL Server가 Employee에서 다른 행을 검사함에 따라이 값이 변경됩니다.
그게 바로 이것이야 쿼리가 평가됩니다 : SQL Server는 각 행의 값을 내부 쿼리로 대체하여 결과에 포함 할 Employee 테이블의 각 행을 고려합니다. 예를 들어 SQL Server가 먼저 Syed Abbas, Employee.BusinessEntityID 변수는 SQL Server가 대체하는 값 285를 사용합니다. 내부 쿼리로 이동합니다.

결과는 0입니다 (Syed Abbas는 보너스를받지 못했습니다. 영업 사원이 아님), 따라서 외부 쿼리는 다음과 같이 평가됩니다.

이것은 false이므로 Syed Abbas는 결과에 포함되지 않습니다.

Write a Comment

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다