DB

[MySQL] UNION과 UNION ALL 완전정복 – 다중 SELECT 결과 통합의 모든 것

인생아 2025. 6. 30. 15:36
반응형

MySQL에서 두 개 이상의 SELECT 결과를 하나로 합쳐서 출력하고 싶을 때 사용하는 명령어가 있다. 바로 UNION과 UNION ALL이다.
단순한 리스트 병합부터 시작해서 다른 테이블의 데이터를 하나의 조회 결과로 보여줘야 할 때, UNION 구문은 매우 강력하고 유용하게 사용된다.

✅ UNION이란?

UNION은 두 개 이상의 SELECT 문 결과를 수직으로 합쳐서 하나의 결과로 보여주는 기능이다.
단, 중복된 결과는 자동으로 제거된다.

기본 문법

SELECT column1, column2 FROM table1
UNION
SELECT column1, column2 FROM table2;

주의사항: 각 SELECT 문에서 선택하는 컬럼 수와 순서, 데이터 타입은 일치해야 한다.

반응형

✅ UNION ALL이란?

UNION ALL은 UNION과 동일한 방식으로 SELECT 결과를 합치지만, 중복된 행도 제거하지 않고 그대로 출력한다.

예시

SELECT name FROM customers_korea
UNION ALL
SELECT name FROM customers_japan;

위 쿼리는 한국 고객과 일본 고객의 이름을 중복 제거 없이 모두 보여준다.

✅ UNION vs UNION ALL 차이점 비교

항목 UNION UNION ALL
중복 제거 여부 중복된 결과 제거 중복된 결과 그대로 유지
성능 상대적으로 느림 (DISTINCT 사용) 빠름
용도 중복된 결과가 의미 없을 때 모든 결과를 보여줘야 할 때
 

✅ 실전 예제: 여러 테이블의 데이터 통합

예제 1: 게시판 통합 조회

SELECT id, title, '공지사항' AS category FROM notice_board
UNION
SELECT id, title, '자유게시판' FROM free_board
UNION
SELECT id, title, 'QnA게시판' FROM qna_board;

이 쿼리는 서로 다른 게시판 테이블을 통합하여, 하나의 리스트로 출력하면서 각 게시판의 이름을 함께 표시한다.

예제 2: 중복 허용이 필요한 로그 통합 (UNION ALL)

SELECT user_id, log_time FROM login_log
UNION ALL
SELECT user_id, log_time FROM error_log;

로그처럼 중복이 중요한 의미를 가지는 데이터는 UNION 대신 UNION ALL을 사용해야 정확한 분석이 가능하다.

반응형

✅ 컬럼 이름은 첫 번째 SELECT 기준이다

UNION 또는 UNION ALL로 합쳐진 결과에서 컬럼명은 첫 번째 SELECT 문에서 정의된 컬럼명이 사용된다.

SELECT name AS customer_name FROM customers_korea
UNION
SELECT name FROM customers_japan;

이 경우 결과의 컬럼명은 customer_name이다.

✅ 정렬 적용 시 주의사항

ORDER BY는 전체 UNION 쿼리의 마지막에 1번만 사용할 수 있다.

SELECT name FROM table1
UNION
SELECT name FROM table2
ORDER BY name;

또는 컬럼 순서를 기준으로 정렬도 가능하다.

SELECT name FROM table1
UNION
SELECT name FROM table2
ORDER BY 1;

✅ UNION을 사용할 때의 성능 팁

  • UNION은 내부적으로 DISTINCT 연산을 수행하므로 많은 데이터가 있을 경우 느려질 수 있다.
  • 중복 제거가 필요 없다면 반드시 UNION ALL을 사용하여 성능을 최적화해야 한다.
  • 각 SELECT 문에 인덱스를 활용하면 전체 쿼리 속도가 향상된다.
  • 서브쿼리로 UNION 결과를 감싸고 필요한 조건만 필터링하여 출력하면 효율적이다.

예시: 필터링된 통합 게시글 조회

SELECT * FROM (
  SELECT id, title, created_at FROM notice_board
  UNION ALL
  SELECT id, title, created_at FROM free_board
) AS merged
WHERE created_at >= CURDATE() - INTERVAL 7 DAY;

✅ UNION을 활용한 보고서 예제

예: 월별 가입자 수 + 탈퇴자 수 통합

SELECT '가입' AS type, COUNT(*) AS cnt, DATE_FORMAT(created_at, '%Y-%m') AS ym
FROM users
GROUP BY ym

UNION ALL

SELECT '탈퇴', COUNT(*), DATE_FORMAT(deleted_at, '%Y-%m') AS ym
FROM users
WHERE deleted_at IS NOT NULL
GROUP BY ym;

이 쿼리는 월별로 가입과 탈퇴를 나란히 보여주는 통계형 보고서를 만들어준다.

✅ 공식 문서 링크

 

반응형