Post

SQL_8 (Subquery)

🙅‍♂️휴대폰으로 볼 때 혹시 글자나 숫자가 화면에 다 안나오면, 휴대폰 가로로 돌리시면 됩니다

1
2
3
4
<목차>

1. 개념
2. 실습


1. 개념

하나의 SQL문 안에 포함된 또 다른 SQL문이다
메인쿼리가 서브 쿼리를 포함하는 종속적인 관계다

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

주의 사항

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

종류

  • Scalar Subquery
    –> Select 절에 사용

  • Inline View
    –> FROM 절에 사용

  • Nested Subquery(중첩 서브 쿼리)
    –> WHERE 절에 사용




2. 실습

2-1) Scalar Subquery

Select 절에서 사용하는 서브쿼리, 결과는 하나의 컬럼이어야함

1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT 컬럼1, (SELECT 컬럼2 FROM 테이블2 WHERE 조건)
FROM 테이블1
WHERE 조건;
⬇️
⬇️
<서울은평경찰서의 강도 검거 건수와 서울시경찰서 전체평균 강도 검거건수를 조회>

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

2-2) Inline view

FROM 절에 사용하는 서브쿼리, 메인쿼리에서는 Inline view에서 조회한 컬럼만 사용 가능

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT a.컬럼, b.컬럼
FROM 테이블1 a, (SELECT 컬럼1, 컬럼2 FROM 테이블2) b
WHERE 조건;
⬇️
⬇️
<경찰서 별로 가장 많이 발생한 범죄 건수와 범죄 유형을 조회>
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;

2-3) Nested Subquery

(1) Single Row Subquery

하나의 열을 검색하는 서브쿼리
서브쿼리가 비교연산자(=, >, ≥, <, ≤, <>, ≠)와 사용되는 경우,
서브쿼리의 검색결과는 한개의 결과값을 가져야 한다 (2개 이상이면 에러)

1
2
3
4
5
6
7
8
9
SELECT 컬럼명
FROM 테이블명
WHERE 컬럼명 = (SELECT 컬럼명
             FROM 테이블명
             WHERE 조건)
ORDER BY 컬럼명;
⬇️
⬇️
SELECT name FROM celab WHERE name = (SELECT host FROM snl_show WHERE id = 1);

(2) Multiple Row (종류 4개)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# IN
# 서브쿼리 결과 중에 포함될 

SELECT 컬럼명
FROM 테이블명
WHERE 컬럼명 IN (
    SELECT 컬럼명 
    FROM 테이블명
    WHERE 조건
)
ORDER BY 컬럼명;
⬇️
⬇️
<snl 출연한 영화배우 조회>
SELECT host 
FROM snl_show
WHERE host IN (
    SELECT name
    FROM celab 
    WHERE JOB_TITLE LIKE '%영화배우%'
);


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# EXISTS
# 서브쿼리 결과에 값이 있으면 반환

SELECT 컬럼명
FROM 테이블명
WHERE 컬럼명 EXISTS (
    SELECT 컬럼명 
    FROM 테이블명
    WHERE 조건
)
ORDER BY 컬럼명;
⬇️
⬇️
<범죄 검거 혹은 발생 건수가 2000 보다  경찰서 조회>
SELECT name
FROM police_station p
WHERE EXISTS (
    SELECT police_station
    FROM crime_status c
    WHERE p.name = c.police_station AND case_number > 2000
);


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# ANY
# 서브쿼리 결과 중에 최소한 하나라도 만족하면 (비교연산자 사용)

SELECT 컬럼명
FROM 테이블명
WHERE 컬럼명 ANY (
    SELECT 컬럼명 
    FROM 테이블명
    WHERE 조건
)
ORDER BY 컬럼명;
⬇️
⬇️
<snl 출연한 적이 있는 연예인 이름 조회>
SELECT name
FROM celab
WHERE name = ANY (
    SELECT host 
    FROM snl_show
);
1
2
3
4
5
6
7
8
9
10
11
# ALL
# 서브쿼리결과를 모두 만족

SELECT 컬럼명
FROM 테이블명
WHERE 컬럼명 ALL (
    SELECT 컬럼명 
    FROM 테이블명
    WHERE 조건
)
ORDER BY 컬럼명;

(3) Multi Column

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT 컬럼명
FROM 테이블명 a
WHERE (a.컬럼1, a.컬럼2, ...) IN (
        SELECT b.컬럼1, b.컬럼2, ...
        FROM 테이블명 b
        WHERE a.컬럼명 = b.컬럼명
    )
ORDER BY 컬럼명;
⬇️
⬇️
<강동원과 성별, 소속사가 같은 연예인의 이름, 성별, 소속사를 조회>
SELECT name, sex, agency
FROM celab
WHERE (sex, agency) IN (SELECT sex, agency FROM celab WHERE name = '강동원');
This post is licensed under CC BY 4.0 by the author.
3D GIF