DB - SQL_ 다중행 연산자(IN/ANY/ALL/UNION/UNION ALL/EXISTS/NOT EXISTS )

윤지영·2024년 4월 17일

IN

  • NULL 값 처리할 수 없다!!!!!!
  • IN 연산자는 주어진 목록 내에 특정 값이 존재하는지를 확인할 때 사용된다.
  • IN 다음에 오는 괄호 안에는 비교 대상이 되는 값들의 목록이나 하위 쿼리(subquery)가 올 수 있다.
  • IN을 사용할 때, 주어진 값이 목록에 포함되어 있다면 참(true)을, 그렇지 않다면 거짓(false)을 반환한다.
SELECT 컬럼명 FROM 테이블명 WHERE 컬럼명 IN (1,2,3, ...);

위 쿼리는 컬럼명이 명시된 값 리스트 (값1, 값2, 값3, ...) 중 하나와 일치하는 모든 행을 찾는다.

NOT IN

주어진 리스트 안에 포함되지 않은 값들을 필터링

-- '기획부'와 '인사부'를 제외한 나머지 부서에 속한 직원들의 이름과 부서
SELECT 이름, 부서
FROM 사원
WHERE 부서 NOT IN ('기획부', '인사부');
-- 
'기획부''인사부'에 속하지 않은 직원들 중에서 급여의 최댓값 검색
SELECT MAX(급여) AS 최대급여
FROM 사원
WHERE 부서 NOT IN ('기획부', '인사부');
  • 서브 쿼리 사용하여 특정 조건에 맞는 데이터를 조회
    SELECT 사원명 FROM 사원
    WHERE 부서 = '영업부' 
    -- 영업부 소속 사원의 이름을 반환하는 조건 
    AND 거주지 IN (  
    -- 영업부 사원 중 기획부 사원과 동일한 거주지를 가진 사원의 이름을 추가로 필터링하는 조건 
       SELECT 거주지 FROM 사원 WHERE 부서 = '기획부'
         -- 서브 쿼리: '기획부' 사원들의 거주지를 반환하는 조건
    );	
    -- 결과 :: 기획부 사원들과 같은 거주지에 사는 영업부 사원명 조회

ANY

ANY는 결과 집합의 '어떤 값이라도' 조건을 만족하면 참이 된다.

-- P123 프로젝트에 참여한 직원들의 급여보다 더 많은 급여를 받는 직원들의 이름과 급여를 조회
SELECT 이름, 급여
FROM 사원
WHERE 급여 > ANY (
    SELECT 급여 FROM 프로젝트참여
    WHERE 프로젝트ID = 'P123'
);

ALL

ALL은 '모든 값'이 조건을 만족해야 참이 된다.

-- 모든 '개발부' 부서 직원의 급여보다 더 많은 급여를 받는 직원들의 이름과 급여를 조회
SELECT 이름, 급여
FROM 사원
WHERE 급여 > ALL (
    SELECT 급여 FROM 사원
    WHERE 부서 = '개발부'
);

UNION

중복 제거한 합집합

UNION ALL

중복 제거하지 않은 합집합

EXISTS

일반적으로 하위 쿼리와 함께 사용되어 특정 조건을 만족하는 데이터가 존재하는지 확인한다.
조건이 참이면 TRUE를, 거짓이면 FALSE를 반환한다.

SELECT 이름
FROM 사원 A
WHERE EXISTS (
    SELECT 1 FROM 프로젝트참여 P
    WHERE P.사원번호 = A.사원번호
    AND P.프로젝트ID = 'P123'
);
  • IN은 주어진 목록이나 하위 쿼리의 결과에 특정 열의 값이 포함되어 있는지 확인할 때 사용. (비교 대상이 되는 값이나 값들의 집합을 명확하게 알고 있을 때 사용)
  • EXISTS는 결과의 특정 값들보다는 결과의 존재 여부가 중요할 때 사용한다. 특히 하위 쿼리의 결과가 복잡하거나, 메인 쿼리의 선택된 행과 직접적인 관계가 있을 때 유용하다. (IN 보다 속도 빠름)

NOT EXISTS

부양 가족이 없는 직원의 이름 찾기
[EMPLOYEE] 직원 정보 저장 릴레이션 (NAME, SSN, ADDR, PHONE)
[DEPENDENT] 부양가족 정보 저장 릴레이션 (SSN, DEPNAME, AGE)
** 단 EMPLOYEE.SSN은 기본키, DEPENDENT.SSN은 외래키이다.

SELECT NAME
FROM EMPLOYEE
WHERE NOT EXISTS (   
    SELECT *
    FROM DEPENDENT
    WHERE EMPLOYEE.SSN = DEPENDENT.SSN
);
  • EMPLOYEE 테이블의 모든 행(직원)에 대해 확인
  • 각 직원의 SSN이 DEPENDENT 테이블의 SSN과 일치하는 행이 있는지 서브 쿼리를 통해 검사
  • 만약 DEPENDENT 테이블에 직원의 SSN과 일치하는 SSN이 있다면, 해당 직원은 부양가족이 존재한다는 의미이므로, 그 직원은 결과에 포함되지 않는다.
    반대로, 만약 DEPENDENT 테이블에 직원의 SSN과 일치하는 SSN이 없다면, 그 직원은 부양가족이 없다는 의미이며, 이 경우에 해당하는 직원의 이름이 결과에 포함된다.

NOT EXISTS 연산자가 사용될 때, 해당 서브쿼리의 조건에 해당하는 행은 검색 결과에서 제외된다. 즉, EMPLOYEE 테이블에서 직원을 검색할 때, 서브쿼리(EMPLOYEE.SSN = DEPENDENT.SSN)의 조건에 해당하는 행들, 즉 DEPENDENT 테이블에 부양가족이 있는 직원은 결과에서 제외된다.

profile
쑥쑥쑥쑥 레벨업🌱🌼🌳

0개의 댓글