UNION과 UNION ALL은 두 개 이상의 SELECT 쿼리의 결과를 결합하는 데 사용되는 SQL 연산자다.
JOIN과의 차이점은 JOIN은 가로로 데이터를 합해주는 느낌이라면, UNION은 새로로 합해주는 느낌이다.
이게 무슨 말이냐면...
각각 위와 같은 모양으로 데이터가 결합하여 조회되기 때문이다.
👇 JOIN 관련 글은 아래 글을 참고해주세요.
1. UNION
- UNION은 UNION DISTINCT와 같은데 코드에 DISTINCT를 명시할 필요는 없다.
- UNION은 중복된 행을 제거한 후에 결과를 반환한다.
- 즉, 여러 SELECT 쿼리에서 같은 데이터가 존재한다면, 하나의 행만 남기고 나머지는 제거한다.
# 기본 구문
SELECT 컬럼1, 컬럼2, ... FROM 테이블1
UNION -- /UNION DISTINCT
SELECT 컬럼1, 컬럼2, ... FROM 테이블2
📚예시
SELECT 배역명, 본명 FROM sweethome1
UNION
SELECT 배역명, 본명 FROM sweethome2;
시즌1과 시즌2 모두에 등장했던 배우 송강과 이진욱, 이시영은 각각 하나의 행만 남겨진다.
2. UNION ALL
- UNION ALL은 중복된 데이터를 제거하지 않고 모든 행을 반환한다.
# 기본 구문
SELECT 컬럼1, 컬럼2, ... FROM 테이블1
UNION ALL
SELECT 컬럼1, 컬럼2, ... FROM 테이블2
📚예시
SELECT 배역명, 본명 FROM sweethome1
UNION
SELECT 배역명, 본명 FROM sweethome2;
시즌1과 시즌2에 모두 참가한 배우 데이터들이 중복 제거 없이 모두 반환되었다.
✅ 주의할 점
1). 결합하려는 SELECT 쿼리들은 컬럼의 개수 및 데이터 타입이 일치해야 한다.
UNION과 UNION ALL은 이 그림처럼 두 SELECT 쿼리의 결과를 하나의 목록으로 이어붙여 하나의 결과 집합을 만들기 때문에 각 쿼리는 동일한 구조(열의 수와 데이터 타입)을 가져야한다. (이때 UNION일 경우 중복된 행은 제거)
2). 결과 집합의 컬럼명은 첫 번째 SELECT 쿼리의 컬럼명이 사용된다.
SELECT 배역명, 본명 FROM sweethome1
UNION
SELECT 배역, 이름 FROM sweethome2;
SELECT id AS id, name AS name FROM users
UNION
SELECT emp_id AS id, full_name AS name FROM customers;
➯ 따라서 SELECT 쿼리의 컬럼명이 다른 경우, 별칭을 사용해 가독성도 높이고 결과 집합의 컬럼명이 예상한 대로 표시되도록 할 수 있게 작성하도록 한다.
3). 컬럼의 순서도 당연히 같아야 한다.
SELECT id, name FROM users
UNION
SELECT name, id FROM customers;
➯ SELECT 쿼리의 컬럼의 개수가 같으면, 컬럼의 순서를 같지 않게 해도 에러가 발생하지는 않는다.
➯ 하지만 위 사진과 같이 의도와는 다른 결과가 초래되니 주의해야 한다.
4). 중복 검사에는 추가적인 연산이 필요하기 때문에, 중복 제거가 필요하지 않다면 혹은 중복될 데이터가 없는 경우라면, UNION ALL을 사용하도록 한다.
5). ORDER BY는 전체 UNION 결과에 대해 마지막에 한 번만 사용 가능하다.
SELECT id, name FROM users
UNION
SELECT id, name FROM customers
ORDER BY name;
6). LIMIT도 전체 UNION 결과에 대해 마지막에 한 번만 사용 가능하다.
SELECT id, name FROM users
UNION
SELECT id, name FROM customers
LIMIT 6;
➯ 개별 쿼리에 LIMIT을 적용하고 싶다면, 서브 쿼리를 이용하면 된다.
Q. 그렇다면 교집합이나 차집합은 어떻게 구할까?
# 교집합 (INTERSECTION)
SELECT id, name FROM users u
WHERE EXISTS (
SELECT 1 FROM customers c
WHERE c.id = u.id AND c.name = u.name
);
# 차집합 (DIFFERENCE)
SELECT id, name FROM users u
WHERE NOT EXISTS (
SELECT 1 FROM customers c
WHERE c.id = u.id AND c.name = u.name
);
➯ WHERE EXISTS와 서브쿼리를 이용해 구할 수 있다.
➯ 여기서 SELECT 1은 단순히 조건을 만족하는 행이 있는지를 확인하는 역할을 한다.
'데이터 분석 > MySQL' 카테고리의 다른 글
MySQL 총 정리11: ROLLUP과 윈도우 함수 (0) | 2024.10.16 |
---|---|
MySQL 총 정리10: 서브쿼리- 스칼라, 인라인 뷰, 중첩 (0) | 2024.10.12 |
MySQL 총 정리8: 테이블 조인(JOIN) (1) | 2024.10.07 |
MySQL 총 정리7: GROUP BY와 HAVING (2) | 2024.10.05 |
MySQL 총 정리6: mysql 내장함수 모음 (4) | 2024.10.03 |