SQL/SQLD

#17 집합 연산자

sundori 2025. 4. 14. 17:19

목차

     

    🧩집합 연산자란?

    SQL에서 두 개 이상의 SELECT 결과를 하나로 조합하거나 비교하는 연산자
    즉, "SELECT + SELECT" → 하나의 결과로 만드는 기술

     

    ✅ 기본 조건 (공통 전제)

    집합 연산자를 쓰려면 아래 조건을 반드시 충족해야 함:

    조건 항목 설명
    컬럼 수 두 SELECT 문의 컬럼 수가 같아야함
    컬럼 순서 컬럼 위치별 타입이 호환되어야함
    컬럼명 결과는 첫 번째 SELECT의 컬럼명 기준으로 표시됨
    students1   students2
    철수 영희
    영희 민수
    민수 지수

    ✅ 1. UNION

    두 SELECT 결과를 합친 후 중복 제거

    📌 문법

    SELECT 컬럼1 FROM 테이블A
    UNION
    SELECT 컬럼1 FROM 테이블B;

    ✅ 중복 제거된 결과만 보여줌

     

    SELECT name FROM students1
    UNION
    SELECT name FROM students2;
    
    --
    철수
    영희
    민수
    지수

    ✅ 2. UNION ALL

    두 SELECT 결과를 합치되, 중복도 포함

    📌 문법

    SELECT 컬럼1 FROM 테이블A
    UNION ALL
    SELECT 컬럼1 FROM 테이블B;

    ✅ 중복이 있어도 전부 표시됨 → 성능 빠름

     

    SELECT name FROM students1
    UNION ALL
    SELECT name FROM students2;
    
    --
    철수
    영희
    민수
    영희
    민수
    지수

    ✅ 3. INTERSECT (교집합)

    두 SELECT 결과 중 공통으로 존재하는 행만 반환

    📌 문법

    SELECT 컬럼1 FROM 테이블A
    INTERSECT
    SELECT 컬럼1 FROM 테이블B;

    ✅ 오라클, PostgreSQL 등 지원
    ❌ MySQL은 기본적으로 INTERSECT 지원 안 함

     

    SELECT name FROM students1
    INTERSECT
    SELECT name FROM students2;
    
    --
    영희
    민수

    ✅ 1. INTERSECT (교집합) ― MySQL에서는 INNER JOIN 또는 IN

    ✅ MySQL 대체 방법 ①: INNER JOIN

    SELECT s1.name
    FROM students1 s1
    INNER JOIN students2 s2
    ON s1.name = s2.name;

    → 두 테이블에서 공통으로 존재하는 name만 추출

     

    ✅ MySQL 대체 방법 ②: IN 사용

    SELECT name
    FROM students1
    WHERE name IN (SELECT name FROM students2);

    → students2에 존재하는 name만 필터링해서 교집합 구현


    ✅ 4. MINUS (또는 EXCEPT)

    첫 번째 SELECT 결과에서 두 번째 SELECT 결과를 뺀 것

    📌 문법 (Oracle 기준)

    SELECT 컬럼1 FROM 테이블A
    MINUS
    SELECT 컬럼1 FROM 테이블B;

    → A - B

    📌 문법 (MySQL / PostgreSQL 기준: EXCEPT 사용)

    SELECT 컬럼1 FROM 테이블A
    EXCEPT
    SELECT 컬럼1 FROM 테이블B;

     

    -- Oracle
    SELECT name FROM students1
    MINUS
    SELECT name FROM students2;
    
    -- PostgreSQL / MySQL (EXCEPT)
    SELECT name FROM students1
    EXCEPT
    SELECT name FROM students2;
    
    --
    철수

     

    ✅ 2. MINUS (차집합) ― MySQL에서는 NOT IN, NOT EXISTS, LEFT JOIN

    ✅ MySQL 대체 방법 ①: NOT IN

    SELECT name
    FROM students1
    WHERE name NOT IN (SELECT name FROM students2);

    → students2에 없는 name만 가져옴 (즉, students1 - students2)

     

    ✅ MySQL 대체 방법 ②: NOT EXISTS

    SELECT name
    FROM students1 s1
    WHERE NOT EXISTS (
      SELECT 1
      FROM students2 s2
      WHERE s1.name = s2.name
    );

    → 더 안전한 방식. NULL이 포함되어 있어도 오류 없이 동작함

     

    ✅ MySQL 대체 방법 ③: LEFT JOIN + IS NULL

    SELECT s1.name
    FROM students1 s1
    LEFT JOIN students2 s2
    ON s1.name = s2.name
    WHERE s2.name IS NULL;

    ✅ 차이점 요약표

    연산자 설명 중복 제거 순서 보장 MySQL 지원
    UNION 합집합 + 중복 제거 O X O
    UNION ALL 합집합(중복 포함) X X O
    INTERSECT 교집합(겹치는 것만) O X X(우회 필요)
    MINUS / EXCEPT 차집합(A에만 있는 것) O X EXCEPT만 일부 지원

    🧠 정리 한줄 요약

    UNION은 합집합(중복 제거),
    UNION ALL은 합집합(중복 포함),
    INTERSECT는 교집합,
    MINUS/EXCEPT는 차집합이다.

    두 SELECT의 컬럼 수와 타입이 같아야 하며,
    MySQL에서는 INTERSECT, MINUS가 기본 지원되지 않음 (우회 필요)

    728x90

    'SQL > SQLD' 카테고리의 다른 글

    #19 윈도우 함수  (0) 2025.04.15
    #18 그룹 함수  (0) 2025.04.14
    #16 뷰(View)  (0) 2025.04.14
    #15 서브쿼리(Subquery)  (0) 2025.04.13
    #14 JOIN  (0) 2025.04.13