1. Subquery

Subquery란?

  • 하나의 SQL 문 안에 포함되어 있는 또 다른 SQL 문을 뜻한다.
    하나의 SQL문은 메인 query라고 하며, 이 안에 포함되어 있는 SQL문을 subquery라고 한다.
  • 메인 query가 subquery를 포함하는 종속적인 관계이다.
    subquery는 메인 query의 column(열) 사용 가능
    메인 query는 subquery의 column(열) 사용 불가능

1.1 Subquery 사용시 주의사항

  • Subquery는 괄호()로 묶어서 사용해야 한다.
  • 단일 행 혹은 복수 행 비교 연산자와 함께 사용 가능하다.
  • subquery에서는 ORDER BY가 사용 불가하다.

1.2 Subquery 종류

  • Scalar Subquery(스칼라 서브쿼리): SELECT 절에 사용
  • Inline View(인라인 뷰): FROM 절에 사용
  • Nested Subquery(중첩 서브쿼리): WHERE 절에 사용

2. Scalar Subquery

Scalar Subquery(스칼라 서브쿼리)는 SELECT 절에서 사용하는 subquery로 결과는 하나의 column 이어야 한다.

Scalar Subquery 문법

SELECT column1, (SELECT column2 FROM table2 WHERE condition)
FROM table1
WHERE condition;

Example: 서울은평경찰서의 강도 검거 건수와 서울시 경찰서 전체의 평균 강도 검거 건수를 조회하기

1) 서울은평경찰서의 강도 검거 건수를 조회하기

select case_number
from crime_status
where police_station like '은평' and crime_type='강도' and status_type='검거';

2) 서울시 경찰서 전체의 평균 강도 검거 건수를 조회하기 (subquery)

select avg(case_number)
from crime_status
where crime_type='강도' and status_type='검거';

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

select case_number,
	(select avg(case_number)
    from crime_status
    where crime_type='강도' and status_type='검거') avg
from crime_status
where police_station like '은평' and crime_type='강도' and status_type='검거';

3. Inline View

Inline View(인라인 뷰)는 FROM 절에 사용하는 subquery로, 메인 query에서는 인라인 뷰에서 조회한 column만 사용 가능하다.

Inline View 문법

SELECT a.column, b.column
FROM table1 a, (SELECT column1, column2 FROM table2) b
WHERE condition;

Example: 경찰서 별로 가장 많이 발생한 범죄 건수의 범죄 유형을 조회하기

1) 경찰서 별로 가장 많이 발생한 범죄 건수 조회하기 (subquery)

select police_station, max(case_number) count
from crime_status
where status_type='발생'
group by police_station; #경찰서 별

2) 경찰서 별로 가장 많이 발생한 범죄 건수의 범죄 유형을 조회하기

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='발생'
    group by police_station) m
where c.police_station = m.police_station
	and c.case_number = m.count;

4. Nested Subquery

Nested Subquery(중첩 서브쿼리)는 WHERE 절에서 사용하는 subquery로,

  • Single Row: 하나의 행(row)을 검색하는 subquery
  • Multiple Row: 하나 이상의 행(row)을 검색하는 subquery
  • Multiple Column: 하나 이상의 열(column)을 검색하는 subquery

4.1 Single Row Subquery

Singble row subquery는 subquery가 비교 연산자(Comparison Operators)(=, >, >=, <=, <, <>, !=)와 사용하는 경우, subquery의 검색 결과는 한 개의 결과값을 가져야 한다.

하지만, 결과값이 두개 이상인 경우, 에러가 발생한다.

Single Row Subquery 문법_

SELECT column_names
FROM table_name
WHERE column_name = (SELECT column_name
					FROM table_name
                    WHERE condition)
ORDER BY column_name;

Example 1: celeb 테이블에서 snl_show 테이블의 host와 같은 데이터 찾기 (괄호( ) X)

select name from celeb
where name = select host from snl_show;

이렇게 괄호( )를 쓰면 에러가 발생하는 걸 확인할 수 있다.

select name from celeb
where name = (select host from snl_show);

위와 같은 query 또한 비교 연산자를 사용함으로 snl_show 테이블에서 한개 이상의 host 결과값을 불러오기에 에러가 발생한다.

Example 2: celeb 테이블에서 snl_show 테이블 중 host의 ID가 1인 데이터 찾기

select name from celeb
where name = (select host from snl_show where id = 1);

4.2 Multiple Row Subquery

1) Multiple Row - IN

Multiple Row - IN 문법

Subquery 결과 중에 포함(IN) 될때

SELECT column_names
FROM table_name
WHERE column_name IN (SELECT column_name
					  FROM table_name
                      WHERE condition)
ORDER BY column_names;

Example: snl_show에 출연한 영화배우를 조회하기

select host
from snl_show
where host in (select name
			   from celeb
               where job_title like '%영화배우%');

위의 문제는 Multiple Row (IN)의 예시로써 IN을 썼지만 JOIN을 쓰는게 더 효율적이다.

2) Multiple Row - EXISTS

Multiple Row - EXISTS 문법

Subquery 결과에 값이 있으면 반환

SELECT column_names
FROM table_name
WHERE EXISTS (SELECT column_name
			  FROM table_name
              WHERE condition)
ORDER BY column_names;

Example: 범죄 검거 혹은 발생 건수가 2000건 보다 큰 경찰서 조회하기

select police_station, reference
from crime_status
where case_number > 2000;

select name
from police_station p
where exists (select police_station
			  from crime_status c
              where p.name = c.reference and case_number > 2000);

3) Multiple Row - ANY

Multiple Row - ANY 문법

Subquery 결과 중에 최소한 하나라도 만족하면 (비교 연산자 사용)

SELECT column_names
FROM table_name
WHERE column_name = ANY (SELECT column_name
					FROM table_name
                    WHERE condition)
ORDER BY column_names;

Example: snl_show에 출연한 적이 있는 연예인 이름 조회하기

select name
from celeb
where name = any (select host
				  from snl_show);

아래처럼 써도 위의 결과값과 똑같다.

select name
from celeb c, snl_show s
where c.name = s.host;

4) Multiple Row - ALL

Multiple Row - ALL 문법

Subquery 결과를 모두 만족하면 (비교 연산자 사용)

SELECT column_names
FROM table_name
WHERE column_name = ALL (SELECT column_name
						 FROM table_name
                         WHERE condition)
ORDER BY column_names;

Example: snl_show의 ID가 1인 host와 동일한 이름을 가진 celeb의 이름 찾기

select name
from celeb
where name = all (select host
				  from snl_show
                  where id = 1);

4.3 Multiple Column Subquery

Multiple Column 문법

subquery 내에 메인 query 열(column)이 같이 사용되는 경우

SELECT column_names
FROM tablename a
WHERE (a.column1, a.column2, ...) IN (SELECT b.column1, b.column2, ...
								  FROM tablename b
                                  WHERE a.column_name = b.column_name)
ORDER BY column_names;

Example: 강동원과 성별, 소속사가 같은 연예인의 이름, 성별, 소속사를 조회하기

select name, sex, agency
from celeb
where (sex, agency) IN (select sex, agency
						from celeb
                        where name = '강동원');

profile
거북선통통통통

0개의 댓글