[헷갈] 서브쿼리

Joo·2024년 4월 30일

RDB & SQL

목록 보기
22/24

서브쿼리(Subquery)란?

하나의 SQL 쿼리문 안에 포함되어 있는 또 다른 쿼리문
메인쿼리가 서브쿼리를 포함하는 종속 관계임

  • 서브쿼리는 메인쿼리 컬럼 사용 가능
  • 메인쿼리는 서브쿼리 컬럼 사용 불가

서브쿼리 사용시 주의

  • 서브쿼리는 괄호로 묶어서 사용해야함
  • 단일 행 or 복수 행 비교 연산자와 함께 사용 가능함
  • 서브쿼리에서는 ORDER BY 사용 불가

서브쿼리 종류

크게 스칼라 서브쿼리, 인라인 뷰, 중첩 서브쿼리로 나뉨

✔️ 스칼라 서브쿼리 (Scalar Subquery)

  • SELECT 절에 사용
  • 프린트 결과는 하나의 컬럼이어야 함

예시)
은평경찰서 강도 검거 건수와 서울시 경찰서 전체의 평균 강도 검거 건수 조회

SELECT case_number,
       (SELECT AVG(case_number)
       FROM crime_status
       WHERE crime_type LIKE '강도' AND status_type LIKE '검거') avg
 FROM  crime_status
 WHERE police_station LIKE '은평' AND crime_type LIKE '강도' AND status_type LIKE '검거';

✔️ 인라인 뷰 (Inline View)

  • FROM 절에 사용
  • 메인쿼리에서는 인라인 뷰에서 조회한 컬럼만 사용 가능

예시)
경찰서 별로 가장 많이 발생한 범죄 건수와 범죄 유형 조회

SELECT c.police_station, c.crime_type, c.case_number
FROM   crime_status c,
       (SELECT police_station, MAX(case_number) count
       FROM crime_status
       WHERE status_type LIKE '발생'
       GROUP BY police_station) m
WHERE  c.police_station = m.police_station
AND    c.case_number = m.count; -- 셀프조인!

✔️ 중첩 서브쿼리 (Nested Subquery)

  • WHERE 절에 사용
  • Single row : 하나의 열을 검색
    • 서브쿼리가 비교 연산자(=, >, >=, <, <=, <>, !=)와 사용되는 경우, 서브쿼리 프린트 결과는 한 개의 결과값을 가져야 함 (두 개 이상인 경우 에러 발생)
  • Multiple row : 하나 이상의 열을 검색 (IN, EXISTS, ANY, ALL)
  • Multiple column : 하나 이상의 행을 검색

예시 - Single row subquery

SELECT name FROM celeb WHERE name = (SELECT host FROM snl_show WHERE id=1);

예시 - Multiple row subquery

SELECT host -- IN 사용 예제 (SNL에 출연한 영화배우 조회)
FROM   snl_show
WHERE  host IN (SELECT name
                FROM celeb
                WHERE job_title LIKE '%영화배우%');

SELECT name -- EXISTS 사용 예제 (범죄 검거 혹은 발생 건수가 2000건 보다 큰 경찰서 조회)
FROM   police_station p
WHERE  EXISTS (SELECT police_station
              FROM crime_status c
              WHERE p.name = c.reference AND case_number > 2000); -- 셀프조인!

SELECT name -- ANY 사용 예제 (서브쿼리 결과 중 최소 하나라도 만족하면 True)
FROM   celeb -- (SNL에 출연한 적이 있는 연예인 이름 조회)
WHERE  name = ANY (SELECT host
                  FROM snl_show);

SELECT name -- ALL 사용 예제 (서브쿼리 결과를 모두 만족하면 비교연산자 사용)
FROM   celeb -- 
WHERE  name = ALL (SELECT host
                  FROM snl_show
                  WHERE id = 1);

WHERE 컬럼명 IN (서브쿼리), WHERE EXISTS (서브쿼리), WHERE 컬럼명 = ANY (서브쿼리), WHERE 컬럼명 = ALL (서브쿼리) 형태를 명심하자!!

예시 - Multiple column subquery

-- 서브쿼리 내에 메인쿼리 컬럼이 같이 사용되는 경우
-- 강동원과 성별, 소속사가 같은 연예인의 이름, 성별, 소속사 조회
SELECT name, sex, agency
FROM   celeb 
WHERE  (sex, agency) IN (SELECT sex, agency FROM celeb WHERE name = '강동원');

Multiple colulmn subquery는 WHERE (컬럼1, 컬럼2, ...) IN (서브쿼리) 형태를 자주 사용함
뿐만 아니라 IN, EXISTS, ANY, ALL, 그리고 비교연산자도 많이 사용함

profile
적당히 공부한 거 정리하는 곳

0개의 댓글