이미지09
Coding Story/DATABASE

[ Oracle ] SQL 서브쿼리 SELECT, FROM, WHERE

반응형

 

 

 

서브쿼리란?

- 하나의 쿼리 문장 내에 포함된 또 하나의 쿼리 문장.

- 비교연산자의 오른쪽에 기술해야 하고 반드시 괄호 안에 넣어야 함.

- 메인 쿼리가 실행되기 이전에 한 번만 실행됨.

 

 

SQL의 기본 문법이자 가장 자주쓰이는 SELECT, WHERE, FROM.

서브쿼리를 각각의 어느 위치에서 사용하냐에 따라 나누어진다.

각각의 종류에 따라 살펴보자.

 

 

 

 

SELECT 절 서브쿼리 ( 스칼라 서브쿼리 )

스칼라 서브쿼리 ( Scalar Subqueries )​ 라고 불리며 SELECT 절 안에 서브쿼리가 들어있다.

이 때, 서브쿼리의 결과는 반드시 단일 행이나 SUM, COUNT 등의 집계 함수를 거친 단일 값으로 리턴되어야 한다.

이유는 서브쿼리를 끝마친 값하나를 메인쿼리에서 SELECT 하기 때문.

 

 

예를 들어 홍길동 학생의 학과를 조회한다고 가정하면 다음과 같다.

SELECT 학생이름,
       (  SELECT 학과.학과이름
            FROM 학과
           WHERE 학과.학과ID = 학생.학생ID ) AS 학과이름
  FROM 학생
 WHERE 학생이름 = '홍길동' ;

 

 

 

 

FROM 절 서브쿼리 ( 인라인뷰 서브쿼리 )

인라인뷰 ( Inline Views ) 라고 불리며 FROM 절 안에 서브쿼리가 들어있다.

이 때, 서브쿼리의 결과는 반드시 하나의 테이블로 리턴되어야 한다.

이유는 서브쿼리를 끝마친 테이블 하나를 메인쿼리의 FROM 에서 테이블로 잡기 때문.

 

수학 과목을 수강하는 학생들의 점수를 조회한다고 가정하면 다음과 같다.

SELECT 학생이름, 수학점수
  FROM ( SELECT 학생.학생이름 AS 학생이름,
                과목.과목점수 AS 수학점수
           FROM 학생, 과목
          WHERE 학생.학생이름 = 과목.학생이름
            AND  과목.과목이름 = '수학' ) ;

 

 

 

 

WHERE 절 서브쿼리 ( 중첩 서브쿼리 )

중첩 서브쿼리 ( Nested Subqueries ) 라고 불리며 WHERE 절 안에 서브쿼리가 들어있다.

가장 자주 쓰이는 대중적인 서브쿼리이며 단일행과 복수행 둘 다 리턴이 가능하다.

이유는 서브쿼리를 끝마친 값들을 메인쿼리의 조건절을 통해 비교등을 하기 때문.

 

수학 과목을 수강하는 학생들의 모든 정보를 조회한다고 가정하면 다음과 같다.

SELECT *
  FROM 학생
 WHERE 학생.학생이름 IN ( SELECT 과목.학생이름 FROM 과목 WHERE 과목.과목이름 = '수학' ) ;

 

이렇게 서브쿼리는 어느 위치에 선언하냐에 따라 나누어진다는 것을 알 수 있다.

 

 

그런데 위에서 언급한 단일행 리턴, 복수행 리턴은 무슨 말인가? 하면 아래를 참고해보자.

 

 

 

 

단일행 서브쿼리

- 서브쿼리의 수행결과가 오직 하나의 ROW(행)만을 반환.

- 이 하나의 결과를 가지고 메인쿼리는 비교연산자를 통해 쿼리를 수행함.

- 비교연산자는 단일행 비교연산자를 사용 ( >, >=, <, <=, =, ... ).

// ex ) 사원들의 평균 급여보다 더 많은 급여를 받는 사원을 검색
SELECT  ENAME, SAL
  FROM  EMP
 WHERE  SAL > ( SELECT  AVG(SAL)
                  FROM  EMP);

 

 

 

 

다중행 서브쿼리

- 서브쿼리의 수행결과가 두 건 이상의 데이터를 반환.

- 비교연산자는 다중행 비교연산자를 사용 ( IN, ANY, SOME, ALL, EXISTS ).

 

다중행 비교연산자가 뭐지?

 

IN

메인쿼리의 비교조건이 서브쿼리의 결과중에서 하나라도 일치하면 참.

ALL

메인쿼리의 비교조건이 서브쿼리의 검색결과와 모든 값이 일치하면 참.

- 메인쿼리 < ALL ( 서브쿼리 ) : 서브쿼리의 결과와 비교하여 최소값 반환.

- 메인쿼리 > ALL ( 서브쿼리 ) : 서브쿼리의 결과와 비교하여 최대값 반환.

// ex ) 30번 소속 사원들 중 급여를 가장 많이 받는 사원보다 더 많은 급여를 받는 사람의 이름과 급여를 출력
SELECT  ENAME, SAL
  FROM  EMP
 WHERE  SAL > ALL ( SELECT  SAL
                      FROM  EMP
                     WHERE  DEPTNO = 30 );

 

ANY

메인쿼리의 비교조건이 서브쿼리의 검색결과와 하나 이상이 일치하면 참.

- 메인쿼리 < ANY ( 서브쿼리 ) : 서브쿼리의 결과와 비교해 메인쿼리의 데이터중 한개라도 서브쿼리 결과보다 작다면 최소값 반환.

- 메인쿼리 > ANY ( 서브쿼리 ) : 서브쿼리의 결과와 비교해 메인쿼리의 데이터중 한개라도 서브쿼리 결과보다 크다면 최대값 반환.

EXISTS

메인쿼리의 비교조건이 서브쿼리의 검색결과중에 하나라도 만족하는 값이 존재하면 참.

EXISTS 는 해당 로우가 존재하는지의 여부만 확인.

IN은 실제 존재하는 데이터들의 모든 값까지 확인.

NOT EXISTS는 메인쿼리의 컬럼명과 서브쿼리의 컬럼명을 비교하여 일치하지 않으면 메인쿼리 테이블의 모든 ROW(행)을 반환.

 

 

 

반응형