Subquery

밤비나·2023년 4월 21일
0

SQL

목록 보기
13/13

SQL에서 서브쿼리(Subquery)는 하나의 SQL 문장 안에 존재하는 또 다른 SQL 문장이다. 즉, 서브쿼리는 다른 쿼리문의 일부로 사용되는 쿼리문이다. 서브쿼리는 외부 쿼리의 결과에 따라 내부 쿼리의 결과가 달라지므로, 서브쿼리를 사용하여 더욱 복잡한 데이터를 추출하거나 조작할 수 있다.

서브쿼리는 크게 세 가지로 나눌 수 있다.

  1. 스칼라 서브쿼리 (Scalar Subquery)
  2. 인라인 뷰 (Inline View)
  3. 중첩 서브쿼리 (Nested Subquery)

Scalar Subquery

Scalar Subquery는 하나의 값 (스칼라 값)을 반환하는 서브쿼리를 말한다. 즉, 서브쿼리의 결과값이 하나의 행과 열로 이루어진 단일 값임을 의미한다.

Scalar Subquery를 사용하면 다른 쿼리에 결과를 반환하여 사용할 수 있다. 일반적으로 WHERE절이나 SELECT문의 칼럼식에서 사용된다.

예시 1) 각 부서의 평균 연봉을 계산

SELECT DepartmentID, AVG(Salary)
FROM Employee
WHERE Salary > (SELECT AVG(Salary) FROM Employee)
GROUP BY DepartmentID;

예시 2) 직원 테이블에서 부서별 가장 높은 급여를 받는 직원의 급여와 부서번호를 출력하는 쿼리

SELECT e.salary, e.department_id
FROM employees e
WHERE e.salary = (
    SELECT MAX(salary) 
    FROM employees 
    WHERE department_id = e.department_id
);

Scalar Subquery는 하나의 값을 반환하기 때문에, 서브쿼리 결과값이 여러 개의 행과 열로 이루어진 경우 에러가 발생할 수 있다. 이 경우 서브쿼리의 결과값을 집계함수나 LIMIT 절을 사용하여 하나의 값을 반환하도록 수정해야 한다.


Inline View

Inline View는 SELECT 문에서 생성된 가상 테이블이다. 다른 말로는 Derived Table, Subquery 또는 Inner Query라고도한다. 뷰와 비슷한 개념이지만 뷰와 달리 따로 저장되지 않고, 다른 쿼리의 일부로 사용되기 때문에 임시로 생성된다.

예제) 매출이 가장 높은 상품의 정보를 조회

SELECT p.product_name, s.sales_amount
FROM product p, sales s
WHERE p.product_id = s.product_id
AND s.sales_amount = (
  SELECT MAX(sales_amount) FROM sales
);

위의 예제에서는 SALES 테이블에서 MAX 함수를 이용하여 매출이 가장 높은 값을 서브쿼리로 조회하고 있다. 이 서브쿼리의 결과를 메인 쿼리와 비교하여, 매출이 가장 높은 상품의 정보를 조회하고 있다.

위 예제에서 FROM 절에서 두 개의 테이블을 참조하고 있는데, 이 때문에 복잡한 조인 조건을 작성해야 할 수도 있다. 이런 경우에도 인라인 뷰를 사용하면 보다 간결하게 SQL을 작성할 수 있다. 아래는 이를 적용한 예시이다.

SELECT p.product_name, s.sales_amount
FROM (
  SELECT MAX(sales_amount) AS sales_amount
  FROM sales
) max_sales, product p, sales s
WHERE p.product_id = s.product_id
AND s.sales_amount = max_sales.sales_amount;

위 예제에서는 sales 테이블에서 매출이 가장 높은 값을 조회하는 서브쿼리를 인라인 뷰로 작성하고 있다. 이를 max_sales라는 가상의 테이블로 처리하여, 이후에 메인 쿼리에서 이를 참조하고 있다. 이렇게 하면, FROM 절에서의 복잡한 조인 조건을 없앨 수 있어 SQL을 보다 간결하게 작성할 수 있다.

Inline View는 다양한 용도로 사용될 수 있다. 예를 들어, SELECT 문에서 하위 쿼리의 결과를 JOIN 하거나, GROUP BY, HAVING, ORDER BY 절에서 사용하여 복잡한 쿼리를 간단하게 작성할 수 있다.

Inline View의 한계는 성능 측면이다. 대부분의 경우, INNER JOIN을 사용하여 Inline View 대신에 다른 쿼리 방식으로 구성하는 것이 성능상 이점이 있을 수 있다. 따라서, 적절한 경우에만 Inline View를 사용해야한다.


Nested Subquery

Nested Subquery란 SQL 쿼리 안에 새로운 서브쿼리를 중첩하여 사용하는 것이다.

Nested Subquery는 다른 서브쿼리와 마찬가지로 SELECT, WHERE, FROM, HAVING, IN, NOT IN, ANY, ALL 절에서 사용될 수 있다. Nested Subquery는 서브쿼리가 하나만 있는 경우와 여러 개가 있는 경우가 있다.

하나의 서브쿼리만 있는 경우, 서브쿼리는 특정 테이블에서 데이터를 검색하고 그 결과를 메인 쿼리에 반환한다. 메인 쿼리는 서브쿼리의 결과를 처리하고 그 결과를 반환한다.

SELECT * FROM employees 
WHERE salary > (SELECT AVG(salary) FROM employees);

employees 테이블에서 salary가 평균 salary보다 큰 데이터를 검색하는 쿼리이다. 이를 위해서는 employees 테이블에서 AVG(salary)를 계산하는 서브쿼리를 사용해야 한다. 이 서브쿼리는 메인 쿼리에서 salary와 비교할 값을 반환한다. 이렇게 서브쿼리는 메인 쿼리에서 비교 연산자와 함께 사용된다.

Nested Subquery에서는 서브쿼리를 중첩하여 사용할 수 있다.

SELECT * FROM employees 
WHERE salary IN (SELECT salary FROM employees WHERE department_id IN 
                  (SELECT department_id FROM departments WHERE location_id = 1700));

employees 테이블에서 location_id가 1700인 부서에 속한 employees 데이터를 검색하는 쿼리이다. 이를 위해서는 departments 테이블에서 location_id가 1700인 department_id를 검색하는 서브쿼리를 사용해야 한다. 그 후, employees 테이블에서 해당 department_id에 속한 salary 데이터를 검색하는 서브쿼리를 중첩하여 사용한다. 이렇게 서브쿼리는 메인 쿼리의 IN 절에서 사용된다.

Nested Subquery는 가독성이 떨어질 수 있으며, 속도가 느릴 수 있다. 따라서 Nested Subquery를 사용하기 전에 다른 방법을 고려해보는 것이 좋다.

profile
씨앗 데이터 분석가.

0개의 댓글