🔥 1. UNION이란?

📖 집합 연산자(합집합, 교집합, 차집합)

연산자설명
UNION두 SELECT 결과를 합친 후 중복 제거
UNION ALL두 SELECT 결과를 합치되 중복을 허용
INTERSECT두 SELECT 결과의 교집합(공통 데이터만 출력)
EXCEPT첫 번째 SELECT 결과에서 두 번째 SELECT 결과를 제외

집합 연산자의 기본 규칙
1. 합칠 SELECT 문들의 열 개수와 데이터 타입이 동일해야 함
2. UNION은 자동으로 중복을 제거 (중복 제거 없이 합치려면 UNION ALL 사용)
3. ORDER BY는 마지막 SELECT 문에서만 사용 가능


🔥 2. UNION 기본 사용법

🎮 예제: 평균 연봉이 3백만 이상이거나 12월에 태어난 선수 찾기

📌 1) 개별 데이터 조회

-- 커리어 평균 연봉이 300만 이상인 선수
SELECT playerID
FROM salaries
GROUP BY playerID
HAVING AVG(salary) >= 3000000;

-- 12월에 태어난 선수
SELECT playerID
FROM players
WHERE birthMonth = 12;

📌 2) UNION으로 합치기

-- 커리어 평균 연봉이 300만 이상이거나 12월에 태어난 선수
SELECT playerID
FROM salaries
GROUP BY playerID
HAVING AVG(salary) >= 3000000
UNION
SELECT playerID
FROM players
WHERE birthMonth = 12
ORDER BY playerID;

📌 UNION은 자동으로 중복을 제거하므로, 같은 선수가 두 조건을 만족해도 한 번만 출력됩니다.


🔥 3. UNION과 UNION ALL 차이점

-- UNION: 중복 제거
SELECT playerID
FROM salaries
GROUP BY playerID
HAVING AVG(salary) >= 3000000
UNION
SELECT playerID
FROM players
WHERE birthMonth = 12
ORDER BY playerID;

-- UNION ALL: 중복 허용
SELECT playerID
FROM salaries
GROUP BY playerID
HAVING AVG(salary) >= 3000000
UNION ALL
SELECT playerID
FROM players
WHERE birthMonth = 12
ORDER BY playerID;

📌 UNION → 중복 제거, UNION ALL → 중복 허용
"보상 지급 로직" 같은 곳에서는 UNION ALL 사용 시 중복 지급 문제가 발생할 수 있음!


🔥 4. INTERSECT (교집합)

📌 "평균 연봉이 3백만 이상이면서 12월에 태어난 선수"

SELECT playerID
FROM salaries
GROUP BY playerID
HAVING AVG(salary) >= 3000000
INTERSECT
SELECT playerID
FROM players
WHERE birthMonth = 12
ORDER BY playerID;

INTERSECT은 두 SELECT 결과에서 공통된 데이터만 반환!


🔥 5. EXCEPT (차집합)

📌 "평균 연봉이 3백만 이상인 선수 중에서 12월생을 제외"

SELECT playerID
FROM salaries
GROUP BY playerID
HAVING AVG(salary) >= 3000000
EXCEPT
SELECT playerID
FROM players
WHERE birthMonth = 12
ORDER BY playerID;

EXCEPT은 첫 번째 SELECT 결과에서 두 번째 SELECT 결과를 빼고 출력!


🔥 6. UNION을 사용할 때 주의할 점

1) SELECT 문들의 열 개수와 데이터 타입이 동일해야 함

-- 오류 발생 (첫 번째 SELECT에는 2개의 열, 두 번째는 1개의 열)
SELECT playerID, AVG(salary)
FROM salaries
GROUP BY playerID
HAVING AVG(salary) >= 3000000
UNION
SELECT playerID
FROM players
WHERE birthMonth = 12;

오류 해결 방법

  • 두 SELECT 문에서 열 개수를 맞추거나 NULL AS 컬럼명을 추가
SELECT playerID, AVG(salary)
FROM salaries
GROUP BY playerID
HAVING AVG(salary) >= 3000000
UNION
SELECT playerID, NULL AS salary
FROM players
WHERE birthMonth = 12;

2) UNION 사용 시 ORDER BY는 마지막 SELECT 문에서만 가능

SELECT playerID
FROM salaries
GROUP BY playerID
HAVING AVG(salary) >= 3000000
UNION
SELECT playerID
FROM players
WHERE birthMonth = 12
ORDER BY playerID; -- ✅ 올바른 사용

SELECT playerID
FROM salaries
GROUP BY playerID
HAVING AVG(salary) >= 3000000
ORDER BY playerID -- ❌ 오류 발생
UNION
SELECT playerID
FROM players
WHERE birthMonth = 12;

🎯 UNION을 사용할 때 고려해야 할 점

중복 제거가 필요하면 UNION, 중복 허용이 필요하면 UNION ALL
"교집합"을 구하려면 INTERSECT, "차집합"을 구하려면 EXCEPT
ORDER BY는 마지막 SELECT 문에서만 가능
열 개수와 데이터 타입이 동일해야 함

📌 "다양한 조건을 조합하여 데이터를 효율적으로 가져오는 방법!"
JOIN과 UNION의 차이점도 추가로 다뤄볼까요? 😊

profile
李家네_공부방

0개의 댓글