티스토리 뷰

SQL

서브쿼리 사용하기

코린이도이 2021. 6. 24. 17:06

서브쿼리

  • 서브쿼리는 다른 SELECT문에 삽입된 SELECT문이다.
  • 서브쿼리를 사용하면 간단한 명령문으로 강력한 기능을 제공하는 명령문을 작성할 수 있다.
  • 테이블 자체 데이터에 종속된 조건을 사용하여 테이블에서 행을 선택할 때 유용하다.
  • 서브쿼리의 사용지침
    • 서브쿼리를 괄호()로 묶어야 한다.
    • 비교조건의 오른쪽에 서브쿼리를 넣는다.
    • 일반적인 서브쿼리에서는 ORDER BY절을 사용하지 않는다.
    • 단일 행 연산자(=,>,<,>=,<=,<>등)와 복수 행 연산자(IN, ANY, ALL)를 사용한다.

 

1. WHERE절 서브쿼리

  • WHERE 조건을 검사하기 위해 서브쿼리 결과를 이용할 수 있다.
  • WHERE절에 사용된 서브쿼리 실행 순서는 서브쿼리를 먼저 수행하고 그 결과값을 이용해 메인 쿼리 조건을 비교하게 된다.
  • 서동명 선수와 같은 팀 소속선수들 이름, 팀id, 포지션을 조회하고 싶은 경우
    (1) 서동명 선수가 소속된 팀정보 조회한다.
    select team_id
    from player
    where player_name = '서동명';
    (2) 1번 문장 결과값을 이용해 해당 팀 선수정보 조회한다.
    SELECT player_name, team_id, position
    FROM player
    WHERE team_id = (1)번 결과(K01)
    (3) 1번, 2번 문장을 서브쿼리 이용해서 SELECT문 통합한다.
    SELECT player_name, team_id, position
    FROM player
    WHERE team_id = (select team_id
                              from player
                              where player_name = '서동명');

 

2. 다중 행 서브쿼리

  • 서브쿼리 결과가 여러 행을 반환하는 경우 다중 행 서브쿼리라고 한다.
  • 같은 값을 비교할 때는 =대신 IN연산자를 사용해 비교작업을 수행한다.
  • ANY, ALL을 사용해 비교작업을 수행하기도 한다.
  • 연산자 설명
    IN 서브쿼리 결과 목록에 있는 임의의 값과 같은지 비교한다.
    ANY 값을 반환되는 각각의 값과 개별 비교해서 조건을 만족하는지 확인한다.
    < ANY는 최대값보다 적음을 의미하고
    > ANY는 최소값보다 큼을 의미하고
    = ANY는 IN과 동일하게 처리된다.
    ALL 서브쿼리에 의해 반환되는 모든 값과 비교한다.
    < ALL은 최소값보다 적음을
    > ALL은 최대값보다 큼을 의미한다.
  • 서브쿼리 결과 여러 건인 경우 모든 결과 만족여부를 검사하는 SQL문
  • SELECT player_name, height
    FROM player
    WHERE height > ALL (selet height
                                  from player
                                  where team_id = 'K02');
  • 여러 건인 서브쿼리 결과 중 최소 하나만 조건 만족되면 결과 추출함
  • SELECT player_name, height
    FROM player
    WHERE height > ANY (select height
                                   from player
                                   where team_id = 'K02');

 

3. FROM절 서브쿼리

  • 서브쿼리는 FROM절에서도 사용 가능하다.
  • 서브쿼리가 FROM절에 명시되면 새로운 데이터 소스를 생성한다.
  • FROM절에 기술한 서브 쿼리는 마치 뷰를 생성하고 뷰를 SELECT문에서 부르는 것과 개념상 비슷하다.
  • 데이터 소스처럼 사용되는 서브쿼리는 저장되지 않는다.
  • SELECT문 일부로서 일시적으로만 존재한다.
  • FROM절에 있는 서브쿼리는 인라인(inline)뷰 라고도 한다.
  • SELECT t.team_name, t.region_name, p.avg_h
    FROM (select team_is, avg(height) avg_h
              from player
              group by team_id) p
             JOIN team t
             ON p.team_id = t.team_id;

 

4. 스칼라 서브쿼리

  • 하나의 행, 하나의 컬럼값만 반환하는 서브 쿼리를 스칼라 서브쿼리라고 한다.
  • 스칼라 서브 쿼리의 값은 서브 쿼리의 SELECT 목록에 있는 항목 값이다.
  • 서브쿼리가 0개의 행을 반환하면 스칼라 서브쿼리의 값은 NULL이 된다.
  • SELECT player_name, team_id, height
              (select avg(height) from player) avg_h
    FROM player;

 

4-1. 스칼라 서브쿼리 사용시 주의점

  • 스칼라 서브쿼리는 열(Column)1개, 행(Row) 1개만 추출하는 서브쿼리를 사용해야 한다.
  • 여러 개의 컬럼을 조회하거나 여러 행(Row)가 추출되는 경우 에러가 발생한다.
  • 아래는 에러를 발생하는 SQL문이다.
  • SELECT player_name, team_id, height
              (select avg(height), avg(weight)
               from player) avg_h
    FROM player;
    SELECT player_name, team_id, height
              (select avg(height) from player
               group by team_id) avg_h
    FROM player;

 

5. 상관 서브 쿼리

  • 메인(바깥쪽) 쿼리의 한 행(Row)에 대해서 서브쿼리가 한번씩 실행된다.
  • 테이블에서 행을 먼저 읽어서 각 행의 값을 관련된 데이터와 비교하는 방법이다.
  • 기본 질의에서 고려된 각 후보 행에 대해 서브쿼리가 다른 결과를 반환해야 하는 경우에 사용된다.
  • 각 행의 값에 따라 응답이 달라지는 질의에 응답할 때 상호연관 서브쿼리를 사용한다.
  • 서브쿼리에서 메인 쿼리의 컬럼명을 사용할 수 있으나, 메인 쿼리에서는 서브쿼리의 컬럼명을 사용할 수 없다.
  • SELECT p.player_name, p.height, p.team_id
    FROM player p
    WHERE p.height > (select avg(height) from player
                               where team_id = p.team_id); -> p.team_id 는 MAIN쿼리 ROW마다
                                                                         team_id 컬럼값을 변경하여 사용하게 된다.
  • 상호 연관 서브 쿼리 실행
    1. 후보 행을 가져온다.(메인 쿼리에서 인출한다.)
    2. 후보 행의 값을 사용하여 서브쿼리를 실행한다.
    3. 서브 쿼리의 결과값을 사용하여 후보 행의 조건을 확인한다.
    4. 후보 행이 남지 않을 때까지 반복한다.
  • 아래는 player 선수 중 본인이 소속된 팀 평균키보다 키가 큰 선수들의 이름, 키, 팀id를 조회하는 SQL문이다.
  • SELECT p.player_name, p.height, p.team_id
    FROM player p
    WHERE p.height > (SELECT avg(height)
                               FROM player
                               WHERE team_id = p.team_id);

 

6. EXISTS 사용하기

  • EXISTS 연산자는 외부 질의에서 검색된 값이 내부 질의의 결과에 존재하는지 여부를 검사하기 위한 상호 연관 서브쿼리에 자주 사용된다.
  • EXISTX 연산자는 서브 쿼리가 한 행 이상 반환하면 TRUE를 반환하고, 해당 값이 없으면 FALSE를 반환한다.
  • SELECT t.team_id, t.team_name, t.region_name
    FROM team t
    WHERE exists (select 1 from player where height > 190 AND team_id = t.team_id);

 

7. NOT EXISTS 사용하기

  • NOT EXISTS는 외부 질의에서 검색된 값이 내부 질의결과에 존재하지 않으면 TRUE, 존재하면 FALSE를 반환한다.
  • SELECT t.team_id, t.team_name, t.region_name
    FROM team t
    WHERE NOT exists ( select 1 from player
                               WHERE height > 190 AND team_id = t.team_id);

 

 

'SQL' 카테고리의 다른 글

[실습 2] 인사 자료 입력하기  (0) 2021.07.02
[실습 1] 인사관리를 위한 테이블 생성하기  (0) 2021.07.01
데이터 결합하기 (JOIN)  (0) 2021.06.21
데이터 변경하기  (0) 2021.06.21
그룹으로 나누기 (GROUP BY)  (0) 2021.06.21
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함