SQL : 17. SQL Subquery

yeppi1802·2024년 6월 13일
0

❇️ 요약

  • Subquery
  • Scalar Subquery / Inline View
  • Nested Subquery
    • Single Row / Multiple Row / Multiple Column

📖 Subquery

이론

🔆 Subquery

  • 하나의 SQL문 안에 포함되어 있는 또 다른 SQL 문을 말한다.
  • 메인쿼리가 서브쿼리를 포함하는 종속적인 관계
    • 서브쿼리는 메인쿼리의 칼럼 사용 가능
    • 메인쿼리는 서브쿼리의 칼럼 사용 불가

📌 Subquery 사용시 주의

  • Subquery는 괄호로 묶어서 사용
  • 단일 행 또는 복수 행 비교 연산자와 함께 사용 가능
  • Subquery에서 order by 사용 X

📌 Subquery 종류

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

📖 Scalar Subquery

🔆 SELECT 절에서 사용하는 서브쿼리

  • 결과는 하나의 Column이어야한다.
SELECT column1, (SELECT column2 FROM table2 WHERE condition)
FROM table1
WHERE condition;

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

SELECT case_number,
       (SELECT avg(case_number)
        FROM crime_status
        WHERE crime_type = '강도'
          AND status_type = '검거') avg
FROM crime_status
WHERE police_station = '은평'
  AND crime_type = '강도'
  AND status_type = '검거';
+-------------+--------+
| case_number | avg    |
+-------------+--------+
|           1 | 4.1935 |
+-------------+--------+
1 row in set (0.01 sec)

📖 Inline View

🔆 FROM 절에 사용하는 서브쿼리

  • 메인 쿼리에서는 인라인 뷰에서 조회한 Column만 사용 가능
SELECT a.column, b.column
FROM table1 a, (SELECT column1, column2 FROM table2) b
WHERE condition;

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

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 |
...
| 도봉           | 폭력       |        1234 |
| 수서           | 폭력       |        1394 |
+----------------+------------+-------------+
31 rows in set (0.00 sec)

📖 Nested Subquery(중첩 서브쿼리)

🔆 WHERE 절에서 사용하는 서브쿼리

Single Row : 하나의 열을 검색하는 서브쿼리
Multiple Row : 하나 이상의 열을 검색하는 서브쿼리
Multiple Column : 하나 이상의 행을 검색하는 서브쿼리

🔆 Single Row

  • 단일행 서브쿼리 연산자 : 비교연산자(=, >, >=, <, <= , <>, !=)
  • SINGLE ROW Subquery의 검색 결과한 개의 결과 값을 가져야 한다. (두개 이상인 경우 에러)
SELECT column_names
FROM table_name
WHERE column_name = (SELECT column_name
                     FROM table_name
                     WHERE condition)
ORDER BY column_name;

☁️ Single Row Subquery 예제

  • 괄호 없이 (에러)
SELECT name FROM celeb WHERE name = SELECT host FROM snl_show;
ERROR 1064 (42000): You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT host FROM snl_show' at line 1
  • 한 개 이상의 결과 (에러)
SELECT name FROM celeb WHERE name = (SELECT host FROM snl_show);
ERROR 1242 (21000): Subquery returns more than 1 row
  • 예제
SELECT name FROM celeb WHERE name = (SELECT host FROM snl_show WHERE id = 1);
+-----------+
| name      |
+-----------+
| 강동원    |
+-----------+
1 row in set (0.00 sec)

🔆 Multiple Row

다중행 서브쿼리 연산자설명
IN서브쿼리 결과중에 포함 될 때
EXISTS서브쿼리 결과에 값이 있으면 반환
ANY서브쿼리 결과중에 최소한 하나라도 만족하면(비교연산자 사용)
ALL서브쿼리 결과를 모두 만족하면(비교 연산자 사용)
  1. IN

    • 서브쿼리 결과중에 포함 될 때
    SELECT column_names
    FROM table_name
    WHERE column_name IN (SELECT column_name
                         FROM table_name
                         WHERE condition)
    ORDER BY column_names;
  2. EXISTS

    • 서브쿼리 결과에 값이 있으면 반환
    SELECT column_names
    FROM table_name
    WHERE EXISTS (SELECT column_name
                  FROM table_name
                  WHERE condition)
    ORDER BY column_names;
  3. ANY

    • 서브쿼리 결과중에 최소한 하나라도 만족하면(비교연산자 사용)
    SELECT column_names
    FROM table_name
    WHERE column_name = ANY (SELECT column_name
                             FROM table_name
                             WHERE condition)
    ORDER BY column_names;
  4. ALL

    • 서브쿼리 결과를 모두 만족하면(비교 연산자 사용)
    SELECT column_names
    FROM table_name
    WHERE column_name = ALL (SELECT column_name
                             FROM table_name
                             WHERE condition)
    ORDER BY column_names;

☁️ Multiple Row 예제

  1. IN : SNL에 출연한 영화배우 조회

    SELECT host
    FROM snl_show
    WHERE host IN (SELECT name
                   FROM celeb
                   WHERE job_title LIKE '%영화배우%');
    +-----------+
    | host      |
    +-----------+
    | 강동원    |
    | 차승원    |
    +-----------+
    2 rows in set (0.01 sec)
  2. EXISTS : 범죄 검거 혹은 발생 건수가 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);
    +--------------------------+
    | name                     |
    +--------------------------+
    | 서울강남경찰서           |
    | 서울강서경찰서           |
    | 서울관악경찰서           |
    | 서울구로경찰서           |
    | 서울노원경찰서           |
    | 서울송파경찰서           |
    | 서울영등포경찰서         |
    | 서울중랑경찰서           |
    +--------------------------+
    8 rows in set (0.00 sec)
  3. ANY : SNL에 출연한 적이 있는 연예인 이름 조회

    SELECT name
    FROM celeb
    WHERE name = ANY (SELECT host
                      FROM snl_show);
    +-----------+
    | name      |
    +-----------+
    | 강동원    |
    | 유재석    |
    | 차승원    |
    | 이수현    |
    +-----------+
    4 rows in set (0.00 sec)
  4. ALL : SNL에 출연한 적이 있고, snl_show의 ID가 1인 연예인 이름 조회

    SELECT name
    FROM celeb
    WHERE name = ANY (SELECT host
                      FROM snl_show
                      WHERE id = 1);
    +-----------+
    | name      |
    +-----------+
    | 강동원    |
    +-----------+
    1 row in set (0.00 sec)

🔆 Multiple Column(연관 서브쿼리)

  • 서브쿼리 내에 메인쿼리 컬럼이 같이 사용되는 경우
SELECT column_names
FROM table_name a
WHERE (a.column1, a.column2, ...) 
               IN (SELECT b.column1, b.column2, ...
                   FROM table_name b
                   WHERE a.column_name = b.column_name)
ORDER BY column_names;

☁️ Multiple Column 예제

  • 강동원과 성별, 소속사가 같은 연예인의 이름, 성별, 소속사를 조회
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)
profile
제로베이스 DA7 김예빈입니다.

0개의 댓글