CH17)SQL Subquery

김지율·2024년 2월 13일
0

데이터분석

목록 보기
18/25

Subquery란

하나의 SQL 문 안에 포함되어 있는 또 다른 SQL 문
• Subquery 는 괄호로 묶어서 사용
• 단일 행 혹은 복수 행 비교 연산자와 함께 사용 가능
• subquery 에서는 order by 를 사용X

1.스카라 서브쿼리 (Scalar Subquery) - SELECT 절에 사용
서울은평경찰서의 강도 검거 건수와 서울시 경찰서 전체의 평균 강도 검거 건수를 조회

mysql> 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 '검거';
+-------------+--------+
| case_number | avg    |
+-------------+--------+
|           1 | 4.1935 |
+-------------+--------+
1 row in set (0.01 sec)

2.인라인 뷰 (Inline View) - FROM 절에 사용
from 절에 사용하는 서브쿼리, 메인쿼리에서는 인라인 뷰에서 조회한 컬럼만 사용가능

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

mysql> 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;
+----------------+------------+-------------+
| police_station | crime_type | case_number |
+----------------+------------+-------------+
| 중부           | 폭력       |         997 |
| 종로           | 폭력       |         964 |
| 남대문         | 절도       |         699 |
| 서대문         | 폭력       |        1292 |
| 혜화           | 폭력       |         747 |
| 용산           | 폭력       |        1617 |
| 성북           | 폭력       |         672 |
| 동대문         | 폭력       |        1784 |
| 마포           | 폭력       |        1844 |
| 영등포         | 폭력       |        2701 |
| 성동           | 폭력       |        1223 |
| 동작           | 폭력       |        1631 |
| 광진           | 폭력       |        1676 |
| 서부           | 폭력       |         748 |
| 강북           | 폭력       |        1817 |
| 금천           | 폭력       |        1471 |
| 중랑           | 폭력       |        2022 |
| 강남           | 폭력       |        2283 |
| 관악           | 폭력       |        2614 |
| 강서           | 폭력       |        2445 |
| 강동           | 폭력       |        1942 |
| 종암           | 폭력       |         758 |
| 구로           | 폭력       |        2204 |
| 서초           | 폭력       |        1750 |
| 양천           | 폭력       |        1582 |
| 송파           | 폭력       |        2675 |
| 노원           | 폭력       |        2163 |
| 방배           | 폭력       |         423 |
| 은평           | 폭력       |        1092 |
| 도봉           | 폭력       |        1234 |
| 수서           | 폭력       |        1394 |
+----------------+------------+-------------

3.중첩 서브쿼리 (Nested Subquery) - WHERE 절에 사용
서브쿼리의 검색 결과는 한 개의 결과값을 가져야 한다. (두개 이상인 경우 에러)

• Single Row - 하나의 열을 검색하는 서브쿼리

mysql> select name from celeb where name=
    -> (select host
    -> from snl_show
    -> where id=1);  
+--------+
| name   |
+--------+
| 강동원 |
+--------+
1 row in set (0.01 sec)

• Multiple Row - 하나 이상의 열을 검색하는 서브쿼리(in, exists, any, all)

SNL 에 출연한 영화배우를 조회

mysql> select host
    -> from snl_show
    -> where host in( select name
    ->                 from celeb
    ->                 where job_title like '%영화배우%');
+--------+
| host   |
+--------+
| 강동원 |
| 차승원 |
+--------+

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

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

SNL 에 출연한 적이 있는 연예인 이름 조회

mysql> select name
    -> from celeb
    -> where name = any(select host
    ->                   from snl_show);
+--------+
| name   |
+--------+
| 강동원 |
| 유재석 |
| 차승원 |
| 이수현 |
+--------+
4 rows in set (0.01 sec)

서브쿼리 결과를 모두 만족하면 (비교 연산자 사용)

mysql> select name 
    -> from celeb
    -> where name = all( select host
    ->                   from snl_show
    ->                   where id=1);
+--------+
| name   |
+--------+
| 강동원 |
+--------+
1 row in set (0.01 sec)

• Multiple Column - 하나 이상의 행을 검색하는 서브쿼리

서브쿼리 내에 메인쿼리 컬럼이 같이 사용되는 경우

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

mysql> select name, sex, agency
    -> from celeb
    -> where (sex, agency) in (select sex, agency from celeb where name='강
동원');
+--------+------+----------------+
| name   | sex  | agency         |
+--------+------+----------------+
| 강동원 | M    | yg엔터테이먼트 |
| 차승원 | M    | yg엔터테이먼트 |
+--------+------+----------------+
2 rows in set (0.01 sec)

문제1.oil_price 테이블에서 셀프주유의 평균가격과 SK에너지의 가장 비싼 가격을
Scalar Subquery 를 사용하여 조회

문제2.oil_price 테이블에서 상표별로 가장 비싼 가격과 상호를 Inline View 를 사용하여 조회하세요

문제3.평균가격 보다 높은 주유소 상호와 가격을 Nested Subquery 를 사용하여 조회하세요

문제4.3번에서 조회한 주유소에서 주유한 연예인의 이름과 주유소, 주유일을
Nested Subquery 를 사용하여 조회하세요. (refueling 테이블)

문제5.refueling 테이블과 oil_price 테이블에서 10만원 이상 주유한 연예인 이름, 상호, 상표, 주유 금액, 가격을
Inline View 를 사용하여 조회하세요.

profile
김지율

0개의 댓글

관련 채용 정보