3 분 소요


UNION 과 UNION ALL 에 대한 정리 및 설명

SQL에서 UNIONUNION ALL은 두 개 이상의 SELECT 쿼리의 결과를 하나로 결합하는 데 사용되는 연산자입니다.
이 두 연산자는 여러 쿼리의 결과를 결합할 때 중요한 역할을 하지만, 서로 다른 동작 방식을 가지고 있습니다.
이 글에서는 UNIONUNION ALL의 차이점, 사용법, 그리고 예제를 통해 각각의 기능을 이해해보겠습니다.



1. UNION

  • UNION 연산자는 두 개 이상의 SELECT 쿼리의 결과를 결합하고, 중복된 행을 제거하여 반환합니다.
  • 즉, 중복을 제거한 유니크한 결과만을 반환합니다.

  • 특징:
    1. 중복 제거: 결과에서 중복된 행은 제거됩니다.
    2. 정렬 수행: 기본적으로 SQL 엔진은 중복을 제거하기 위해 정렬 작업을 수행하기 때문에, 비교적 더 많은 리소스를 사용합니다.
    3. 컬럼 수와 타입 일치: 결합하는 모든 쿼리의 컬럼 수와 데이터 타입이 동일해야 합니다.


  • 문법:
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
  • 예제: 두 테이블에서 서로 다른 고객 목록을 결합하기
# `Customers_Online` `Customers_Offline` 테이블에서 중복되는 고객을 제거하고 유일한 고객 목록을 반환합니다.
SELECT customer_id, customer_name FROM Customers_Online
UNION
SELECT customer_id, customer_name FROM Customers_Offline;


2. UNION ALL

  • UNION ALL 연산자는 두 개 이상의 SELECT 쿼리의 결과를 결합하며, 중복된 행을 제거하지 않고 모두 반환합니다. 이로 인해 중복된 데이터도 모두 출력됩니다.
  • 특징:
    1. 중복 허용: 중복된 행도 그대로 반환합니다.
    2. 성능 우위: 중복을 제거하기 위한 정렬 작업을 하지 않기 때문에, UNION보다 빠릅니다.
    3. 컬럼 수와 타입 일치: 결합하는 모든 쿼리의 컬럼 수와 데이터 타입이 동일해야 합니다.


  • 문법:
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;
  • 예제: 두 테이블에서 중복을 허용하여 고객 목록 결합하기
# `Customers_Online` `Customers_Offline` 테이블의 고객 목록을 중복된 행까지 포함하여 모두 반환합니다.
SELECT customer_id, customer_name FROM Customers_Online
UNION ALL
SELECT customer_id, customer_name FROM Customers_Offline;


3. UNION UNION ALL의 차이점

특징 UNION UNION ALL
중복된 행 중복된 행을 제거 중복된 행을 제거하지 않음
성능 중복 제거를 위해 더 많은 리소스 사용 중복 제거를 하지 않으므로 더 빠름
정렬 작업 중복을 제거하기 위해 정렬이 필요함 정렬 작업이 필요하지 않음
사용 목적 중복 없는 결과를 원할 때 사용 모든 데이터를 그대로 출력할 때 사용


4. 사용 시 주의사항

  1. 컬럼 수와 데이터 타입:
    • UNION 또는 UNION ALL을 사용할 때, 결합하는 쿼리의 컬럼 수와 데이터 타입이 동일해야 합니다.
    • 각 컬럼의 순서도 동일해야 합니다. 예를 들어 첫 번째 컬럼이 숫자 타입이면, 두 번째 쿼리의 첫 번째 컬럼도 숫자 타입이어야 합니다.
  2. 성능 차이:
    • UNION ALL은 중복을 제거하지 않으므로 더 빠르게 작동합니다.
    • UNION은 중복된 데이터를 제거하기 위해 정렬 작업이 필요하기 때문에 더 많은 리소스가 필요합니다. 데이터 양이 많을 때 성능에 영향을 줄 수 있습니다.
  3. 중복 처리 여부:
    • UNION은 중복된 데이터를 제거하여 반환하므로, 결과에서 중복을 원치 않을 때 유용합니다.
    • 반대로, 모든 데이터를 반환하고자 할 때는 UNION ALL을 사용하는 것이 적합합니다.


JOIN

CROSS JOIN

  • CROSS JOIN은 모든 데이터가 서로 곱해서 출력됩니다.
  • 또는 각각의 테이블을 콤마( , )를 이용해 이으면 모든 데이터가 서로 곱해서 출력됩니다.
-- cross join 
SELECT *
    FROM EMP
    CROSS JOIN DEPT;

-- ,로 연결 
SELECT * 
    FROM EMP, DEPT;


1. 집계 함수와 JOIN의 조합

  • 서브쿼리에서 부서별 최대 급여를 구한 후, 이를 JOIN하여 해당 급여를 받는 직원을 찾습니다.
  • # 예제: 부서별로 가장 높은 급여를 받는 직원 찾기
    SELECT e.employee_name, e.salary, e.department_id
    FROM employees e
    JOIN (
    SELECT department_id, MAX(salary) AS max_salary
    FROM employees
    GROUP BY department_id
    ) AS dept_max
    ON e.department_id = dept_max.department_id AND e.salary = dept_max.max_salary;
    


2. SELF JOIN 활용

  • 자기 자신과의 JOIN을 통해 같은 부서에 속하지만, 다른 직원들을 조회할 수 있습니다.
# 예제: 직원 테이블에서 같은 부서에 속한 직원을 찾기
SELECT e1.employee_name AS employee, e2.employee_name AS colleague
FROM employees e1
JOIN employees e2
ON e1.department_id = e2.department_id
WHERE e1.employee_id <> e2.employee_id;


3. EXISTS 서브쿼리와 JOIN의 결합

  • EXISTS는 서브쿼리가 결과를 반환하면 TRUE를 반환합니다. 따라서, 직원이 있는 부서만 결과로 반환됩니다.
# 예제: 부서에 직원이 존재하는 부서만 조회하기
SELECT d.department_name
FROM departments d
WHERE EXISTS (
    SELECT 1
    FROM employees e
    WHERE e.department_id = d.department_id
);


WHERE vs ON vs HAVING

이해 포인트
WHERE: 행 단위로 데이터를 필터링합니다. 조인이나 그룹화 전에 사용됩니다.
ON: 테이블을 결합할 때 어떤 조건으로 결합할지 지정합니다.
HAVING: 그룹화된 결과에 대해 추가로 조건을 적용할 때 사용됩니다.

1. WHERE

  • 목적: 개별 행을 필터링합니다.
  • 적용 시점: 테이블에서 데이터를 조인하기 전에 각 행에 대해 조건을 적용합니다.
  • 사용 위치: 일반적으로 SELECT, UPDATE, DELETE 문에서 사용됩니다.
  • 예시:
    # 주문 날짜가 2024 1 1 이후인 행만 선택합니다.
    SELECT * 
    FROM Orders 
    WHERE order_date > '2024-01-01';
    


2. ON

  • 목적: 테이블 간의 조인 조건을 지정합니다.
  • 적용 시점: 두 테이블을 조인할 때 조건을 적용합니다.
  • 사용 위치: JOIN 문과 함께 사용됩니다.
  • 예시:
    # `Orders` `Customers` 테이블을 고객 ID 기준으로 결합합니다.
    SELECT * 
    FROM Orders O
    JOIN Customers C 
    ON O.customer_id = C.customer_id;
    

ON 절에 조건을 포함시키면, 이 조건은 테이블이 결합될 때 즉시 적용됩니다.
즉, 두 테이블이 조인될 때, 조건에 맞는 행만 결합되고, 그렇지 않은 경우에는 NULL이 반환됩니다.
하지만 왼쪽 테이블의 모든 행은 유지됩니다.


3. HAVING

  • 목적: 그룹화된 데이터를 필터링합니다.
  • 적용 시점: 그룹화 및 집계된 후 조건을 적용합니다.
  • 사용 위치: GROUP BY 문 뒤에 사용됩니다.
  • 예시:
    # 고객별로 주문 금액을 합산한 ,  합계가 1000 초과하는 그룹만 선택합니다.
    SELECT customer_id, SUM(order_amount) AS total_spent
    FROM Orders
    GROUP BY customer_id
    HAVING total_spent > 1000;
    


  • 세 절의 비교 요약

    주요 목적 적용 시점 사용 위치
    WHERE 개별 행 필터링 조인 전 또는 그룹화 전 SELECT, UPDATE, DELETE
    ON 테이블 간의 조인 조건 지정 조인 시점 JOIN
    HAVING 그룹화된 데이터 필터링 그룹화 및 집계 후 GROUP BY

댓글남기기