MySQL 문법 및 예제 정리 - UNION, UNION ALL, join
UNION 과 UNION ALL 에 대한 정리 및 설명
SQL에서 UNION
과 UNION ALL
은 두 개 이상의 SELECT 쿼리의 결과를 하나로 결합하는 데 사용되는 연산자입니다.
이 두 연산자는 여러 쿼리의 결과를 결합할 때 중요한 역할을 하지만, 서로 다른 동작 방식을 가지고 있습니다.
이 글에서는 UNION
과 UNION ALL
의 차이점, 사용법, 그리고 예제를 통해 각각의 기능을 이해해보겠습니다.
1. UNION
UNION
연산자는 두 개 이상의 SELECT 쿼리의 결과를 결합하고, 중복된 행을 제거하여 반환합니다.-
즉, 중복을 제거한 유니크한 결과만을 반환합니다.
- 특징:
- 중복 제거: 결과에서 중복된 행은 제거됩니다.
- 정렬 수행: 기본적으로 SQL 엔진은 중복을 제거하기 위해 정렬 작업을 수행하기 때문에, 비교적 더 많은 리소스를 사용합니다.
- 컬럼 수와 타입 일치: 결합하는 모든 쿼리의 컬럼 수와 데이터 타입이 동일해야 합니다.
- 문법:
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 쿼리의 결과를 결합하며, 중복된 행을 제거하지 않고 모두 반환합니다. 이로 인해 중복된 데이터도 모두 출력됩니다.- 특징:
- 중복 허용: 중복된 행도 그대로 반환합니다.
- 성능 우위: 중복을 제거하기 위한 정렬 작업을 하지 않기 때문에,
UNION
보다 빠릅니다. - 컬럼 수와 타입 일치: 결합하는 모든 쿼리의 컬럼 수와 데이터 타입이 동일해야 합니다.
- 문법:
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. 사용 시 주의사항
- 컬럼 수와 데이터 타입:
UNION
또는UNION ALL
을 사용할 때, 결합하는 쿼리의 컬럼 수와 데이터 타입이 동일해야 합니다.- 각 컬럼의 순서도 동일해야 합니다. 예를 들어 첫 번째 컬럼이 숫자 타입이면, 두 번째 쿼리의 첫 번째 컬럼도 숫자 타입이어야 합니다.
- 성능 차이:
UNION ALL
은 중복을 제거하지 않으므로 더 빠르게 작동합니다.UNION
은 중복된 데이터를 제거하기 위해 정렬 작업이 필요하기 때문에 더 많은 리소스가 필요합니다. 데이터 양이 많을 때 성능에 영향을 줄 수 있습니다.
- 중복 처리 여부:
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
뒤
댓글남기기