하위 쿼리 관련 작업하기

하위 쿼리는 다른 쿼리 내의 쿼리입니다. FROM 또는 WHERE 절의 하위 쿼리는 포함하는 쿼리에서 반환되는 데이터를 제한 또는 비교/평가하기 위해 사용할 데이터를 제공하기 위해 사용됩니다.

이 항목의 내용:

하위 쿼리의 타입

상관 vs 비상관 하위 쿼리

하위 쿼리는 상관 또는 비상관 으로 카테고리를 나눌 수 있습니다.

  • 상관 하위 쿼리는 하위 쿼리 외부에서 1개 이상의 열을 참조합니다. (열은 일반적으로 하위 쿼리의 WHERE 절 내에서 참조됩니다.) 상관 하위 쿼리는 하위 쿼리가 외부 쿼리에 위치한 테이블의 각 행에서 평가된 것처럼 참조하는 테이블의 필터로 생각할 수 있습니다.

  • 비상관 하위 쿼리의 경우에는 이러한 외부 열 참조가 없습니다. 그리고 독립적인 쿼리로, 쿼리의 결과는 외부 쿼리에 한 번만 반환 및 사용됩니다(행당 아님).

예:

-- Uncorrelated subquery:
SELECT c1, c2
  FROM table1 WHERE c1 = (SELECT MAX(x) FROM table2);

-- Correlated subquery:
SELECT c1, c2
  FROM table1 WHERE c1 = (SELECT x FROM table2 WHERE y = table1.c2);
Copy

스칼라 vs 비스칼라 하위 쿼리

하위 쿼리는 스칼라 또는 비스칼라 로 카테고리를 나눌 수 있습니다.

  • 스칼라 하위 쿼리는 단일 값(1개 행의 1개 열)을 반환합니다. 반환할 행이 없으면 하위 쿼리는 NULL을 반환합니다.

  • 비스칼라 하위 쿼리는 0개, 1개 또는 여러 개의 행을 반환하며, 각 행에는 1개 또는 여러 개의 열이 포함될 수 있습니다. 각 열에 반환할 값이 없으면 하위 쿼리는 NULL을 반환합니다. 반환할 행이 없으면 하위 쿼리는 0개 행(NULLs 아님)을 반환합니다.

Snowflake에서 지원되는 타입

현재 Snowflake에서 지원하는 하위 쿼리의 타입은 다음과 같습니다.

  • 값 식을 사용할 수 있는 모든 위치의 비상관 스칼라 하위 쿼리.

  • WHERE 절의 상관 스칼라 하위 쿼리.

  • WHERE 절의 EXISTS, ANY / ALL 및 IN 하위 쿼리. 이러한 하위 쿼리는 상관 또는 비상관일 수 있습니다.

하위 쿼리 연산자

하위 쿼리 연산자 는 중첩된 쿼리 식에서 작동합니다. 그리고 다음과 같은 값을 계산하기 위해 사용될 수 있습니다.

  • SELECT 목록에서 반환된 값.

  • GROUP BY 절에서 그룹화된 값.

  • WHERE 또는 HAVING 절에서 다른 값과 비교된 값.

상관 및 비상관 하위 쿼리의 차이점

다음 쿼리는 WHERE 절에서의 비상관 하위 쿼리를 보여줍니다. 하위 쿼리는 브라질의 1인당 GDP를 가져오며, 외부 쿼리는 브라질의 1인당 GDP보다 급여가 모든 직무(모든 국가)를 선택합니다. 반환되는 값은 외부 쿼리의 열과 독립적이므로 하위 쿼리는 상관 관계가 없습니다. 하위 쿼리는 외부 쿼리의 전체 실행 중에 1회만 호출하면 됩니다.

SELECT p.name, p.annual_wage, p.country
  FROM pay AS p
  WHERE p.annual_wage < (SELECT per_capita_GDP
                           FROM international_GDP
                           WHERE name = 'Brazil');
Copy

다음 쿼리는 WHERE 절에서의 상관 하위 쿼리를 보여줍니다. 이 쿼리에서는 해당 국가에서 직무의 연간 급여가 1인당 GDP보다 작은 직무를 나열합니다. 이 하위 쿼리는 외부 쿼리의 각 행에 대해 1회 호출되고 행에서 p.country (국가 이름) 값이 전달되므로 상관 관계가 있습니다.

SELECT p.name, p.annual_wage, p.country
  FROM pay AS p
  WHERE p.annual_wage < (SELECT MAX(per_capita_GDP)
                           FROM international_GDP i
                           WHERE p.country = i.name);
Copy

참고

international_GDP 테이블에는 국가당 행이 1개이므로, 이 경우에는 논리적으로 MAX 집계 함수가 필요하지 않습니다. 그러나 서버는 이를 알지 못하고 서버에서는 하위 쿼리가 1개 이상의 행이 반환되지 않아야 하므로, 쿼리는 집계 함수를 사용하여 하위 쿼리가 실행될 때마다 하위 쿼리가 1개의 행만 반환해야 함을 서버에 통지합니다.

MINAVG 함수도 작동합니다. 왜냐하면 이러한 함수 중 하나를 단일 값에 적용하면 변경되지 않은 값을 반환하기 때문입니다.

스칼라 하위 쿼리

스칼라 하위 쿼리는 최대 1개의 행을 반환하는 하위 쿼리입니다. 스칼라 하위 쿼리는 SELECT 목록, GROUP BY 절 또는 함수의 인자로써 WHERE 또는 HAVING 절 등의 값 식이 표시될 수 있는 모든 위치에 표시될 수 있습니다.

사용법 노트

  • 스칼라 하위 쿼리에는 SELECT 목록에 1개의 항목만 포함할 수 있습니다.

  • 스칼라 하위 쿼리에서 행이 1개 이상 반환되는 경우에는 런타임 오류가 발생합니다.

  • 상관 스칼라 하위 쿼리는 현재 1개 행을 반환하도록 정적으로 결정할 수 있는 경우(예: SELECT 목록에 GROUP BY 를 제외한 집계 함수가 포함된 경우)에만 지원됩니다.

  • 비상관 스칼라 하위 쿼리는 값 식이 허용되는 곳이면 어디서든 지원됩니다.

  • FLATTEN 내에 상관 관계가 있는 하위 쿼리는 현재 지원되지 않습니다.

  • LIMIT / FETCH 절은 비상관 스칼라 하위 쿼리에서만 허용됩니다.

이 예는 WHERE 절에서의 기본 비상관 하위 쿼리를 보여줍니다.

SELECT employee_id
FROM employees
WHERE salary = (SELECT max(salary) FROM employees);
Copy

이 예에서는 FROM 절에서 비상관 하위 쿼리를 보여주며, 이 기본 하위 쿼리는 international_GDP 테이블에 있는 정보의 하위 세트를 반환합니다. 전체 쿼리는 직무의 연간 급여가 해당 국가의 per_capita_GDP와 동일한 “고임금” 국가의 직무를 나열합니다.

SELECT p.name, p.annual_wage, p.country
  FROM pay AS p INNER JOIN (SELECT name, per_capita_GDP
                              FROM international_GDP
                              WHERE per_capita_GDP >= 10000.0) AS pcg
    ON pcg.per_capita_GDP = p.annual_wage AND p.country = pcg.name;
Copy

제한 사항

하위 쿼리에는 다양한 SELECT 문이 포함될 수 있지만, 다음과 같은 제한 사항이 있습니다.

  • 일부 절은 ANY/ALL/NOT EXISTS 하위 절 내에서 허용되지 않습니다.

  • LIMIT / FETCH 절을 허용하는 유일한 하위 쿼리 타입은 비상관 스칼라 하위 쿼리입니다. 또한, 비상관 스칼라 하위 쿼리는 1개 행만 반환하므로, LIMIT 절에는 하위 쿼리 내에 실제 값이 적거나 없을 수 있습니다.