39_[db]서브쿼리 subquery
서브쿼리 Subquery
- SQL문을 실행하는데 필요한 데이터를 추가로 조회하기 위해 SQL문 내부에서 사용하는 SQL문
(예: A 사원의 사수에 대한 정보를 하나의 쿼리를 통해서 확인해보고 싶은 경우)
What is “Subquery”?
📌 서브쿼리의 특징 📌
- 연산자 등과 같은 비교, 조회 도구의 오른쪽에 위치
(예)
SELECT *
FROM EMP
WHERE SAL > (
SELECT SAL
FROM EMP
WHERE ENAME='JAMES'
):
- 대부분은, 서브쿼리 내부에서 ORDER BY 절을 사용할 수 없음(예외의 대표적 경우-
Top-N 분석과 같이, 먼저 정렬된 데이터가 필요한 경우)
- 서브쿼리의 SELECT 절에 명시된 자료형, 열의 갯수 == 메인쿼리의 비교대상과 같은 자료형, 열 갯수
(예)
SELECT *
FROM EMP
WHERE SAL > (
SELECT SAL
FROM EMP
WHERE ENAME='JAMES'
):
WHERE절의 부등호를 기준으로 왼쪽과 오른쪽 모두 NUMBER 형, 열 갯수 1개!
- 서브쿼리의 SELECT 문의 결과 행수: 메인쿼리의 연산자 종류와 호환되어야!
- 단일행 서브쿼리는 단일행 연산자와!
- 다중행 서브쿼리는 다중행 연산자와!
서브쿼리의 실행 결과가 한 행으로 나오는지, 여러 행이 나오는 지에 따라서!
1. 단일행 서브쿼리
- 단일행 서브쿼리에서 사용되는 연산자:
- WHERE 절에 그룹 함수(=다중행 함수=결과가 한 행으로 나오는 함수 = 여러 행에 대한 연산을 수행하는 함수)가 나올 수 있음
2. 다중행 서브쿼리
- 서브쿼리의 결과가 여러행인 경우가 해당됨
- 다중행 연산자의 종류
- IN 연산자
SELECT 컬럼명
FROM 테이블
WHERE 컬럼명 IN(A,B);
- ANY, SOME, ALL 연산자
SELECT 컬럼명
FROM 테이블
WHERE 컬럼명 ANY/SOME/ALL(서브쿼리);
- EXISTS 연산자
SELECT 컬럼명
FROM 테이블
WHERE EXISTS(서브쿼리);
--예
SELECT *
FROM EMP
WHERE EXISTS(SELECT DNAME
FROM DEPT
WHERE DEPTNO = 10);
3. 다중열, 다중열 다중행 서브쿼리- 단일행과 다중행에 열을 섞은 느낌!
SELECT 컬럼명
FROM 테이블
WHERE (컬럼,컬럼) (단일/다중행 연산자)(서브쿼리);
- 다중열, 다중열 다중행 서브쿼리는 여러 컬럼을 비교할 때 사용하는 서브쿼리!
- 그 중 다중열 다중행 서브쿼리는 다중열 서브쿼리에 의미적으로 포함될 수 있는 서브쿼리로,
서브쿼리의 결과가 여러행인 경우! 이면서! 비교하는 컬럼이 여러개!
인라인 뷰
- FROM 절에 사용하는 서브쿼리
- (나중에 객체 부분에 나오는 프로시져와 의미는 비슷) SELECT 조회 결과를 화면처럼 찍어두고, 그 화면 내에서 조회하는 경우
(예)
SELECT ENAME, LOC
FROM (
SELECT EMP_NAME, DEPT_TITLE
FROM EMPLOYEE
JOIN DEPARTMENT ON(DEPT_CODE=DEPT_ID)
);
- 실질적으로 사용하는 컬럼 갯수 ≤ 전체 테이블의 컬럼 갯수 인경우 불필요한 컬럼이 너무 많은 점을 해결해줄 수 있음
WITH 절
- FROM 절에 너무 많은 서브쿼리를 지정하면, 가독성이나 성능이 저하될 수 있기 때문에 나타난 방법(오라클 9i~)
WITH
별칭1 AS 서브쿼리1,
별칭2 AS 서브쿼리2,...
SELECT
FROM 별칭1,...,별칭N;
--예시--
WITH
SAL$AVG AS (
SELECT DEPTNO AS 부서코드,
TRUNC(AVG(SAL)) AS 부서별평균급여
FROM EMP
GROUP BY DEPTNO
)
SELECT *
FROM SAL$AVG
ORDER BY 부서코드;--서브쿼리 내에서 DEPTNO를 별칭으로
--접근했다면, 별칭으로 접근해야!
상호연관 서브쿼리=상관 서브쿼리 “Correlated Subquery”
- 메인 쿼리에 사용한 데이터를 서브 쿼리에서 사용하고, 서브 쿼리의 결과값을 다시 메인쿼리로 돌려주는 방식
SELECT 컬럼명
FROM **테이블명1**
WHERE 컬렴/표현식 OPERATOR (
SELECT 컬럼/표현식
FROM **테이블명2**
WHERE **테이블명2.컬럼** OPERATOR **테이블명1.컬럼);**
reference: 상호연관_서브쿼리
스칼라 서브쿼리 Scala Subquery
- SELECT 절에 사용되는 서브쿼리
예시)
SELECT EMPNO,
(SELECT GRADE
FROM SALGRADE
WHERE E.SAL BETWEEN LOSAL AND HISAL) AS SALGRADE --비등가조인
FROM EMP E;