SQLD/SQL 기본과 활용
단일행 서브쿼리(Single Row SubQuery), 다중행 서브쿼리(Multi Row SubQuery), 다중 칼럼 서브쿼리(Multi Column SubQuery), 연관 서브쿼리(Correlated Subquery)
DevPing9_
2020. 8. 27. 21:29
# 서브쿼리가 좋을지 조인이 좋을지는 옵티마이저가 판단하여 실행하므로, 서브쿼리로 인한 성능저하는 걱정하지 않아도 된다.
# 하지만, 서브쿼리로 테이블 접근횟수가 늘어나는 것은 지양해야한다.
# 서브쿼리는 괄호로 감싸서 기술한다.
1. 단일행 서브쿼리
- 리턴값이 1개 이하인 서브쿼리
- 단일행 비교연산자와 사용
ex) =, <, <=, >=, >, <>
SQL> SELECT PNAME, POSITION
FROM PLAYER
WHERE HEIGHT <= (SELECT AVG (HEIGHT) FROM PLAYER);
# 실행결과 (모든플레이어의 평균키보다 작거나 같은선수들을 출력)
PNAME POSITION
----------------------
고종수 CB
이천수 FW
종아리 GK
2. 다중행 서브쿼리
- 리턴값이 여러행
- 다중행 비교연산자와 사용
ex) IN, ALL, ANY, SOME, EXISTS
# 이천수라는 선수가 2명이고 속한 팀이 다르다고 가정한다.
# IN 연산자
SQL> SELECT T_NAME
FROM TEAM
WHERE TEAM_ID IN (SELECT TEAM_ID FROM PLAYER WHERE PNAME = '이천수');
# 조인이 아니다. 단순 연산일뿐
# 실행결과 (서브쿼리의 리턴행은 2개이고 그 두개 행중에 속한다면 출력)
T_NAME
-----------------------
맨체스터유나이티드
바르셀로나
3. 다중칼럼 서브쿼리
- SQL Server 에서 지원되지 않음 (Oracle은 지원)
- 비교칼럼 갯수가 같아야 함
# D_AVSAL 은 각 부서별 평균연봉이며 백의 자리까지 반올림한 INT형으로 저장되어있다.
# IN 연산자
SQL> SELECT A.E_NAME, B.D_NAME
FROM EMP A JOIN DEPT B
ON B.DEPTNO = A.DEPTNO
# DEPT 테이블을 가져온건, 서브쿼리로 불러온 칼럼은 메인 쿼리의 SELECT 절에 사용할 수 없기 때문)
# 반대로 서브쿼리에선 메인쿼리의 컬럼을 사용 가능하다..
WHERE (A.SAL, A.DEPTNO) IN (SELECT D_AVSAL, DEPTNO FROM DEPT GROUP BY DEPTNO);
# 실행결과
# (서브쿼리의 리턴칼럼은 2개이다. 각 부서별로 평균연봉이 기입된 데이터가 리턴값이다)
# (각 부서별 사원중 정확히 각 부서별 평균연봉을 가진 사원들을 모두 출력한다, 두 조건을 다 만족하는 데이터)
E_NAME D_NAME
-----------------------
구르미 영업
바나나 영업
토마토 유통
부르릉 생산
4. 연관 서브쿼리
- 서브쿼리 내에 메인쿼리 칼럼이 사용된 서브쿼리
- EXISTS 서브쿼리는 항상 연관 서브쿼리로 사용된다.
# 연관서브쿼리 (서브쿼리내에 A.DEPTNO가 존재)
SQL> SELECT A.E_NAME, A.DEPTNO, A.SAL
FROM EMP A
WHERE A.SAL < (SELECT AVG (X.SAL) FROM EMP X
WHERE X.DEPTNO = A.DEPTNO
GROUP BY X.DEPTNO);
# 실행결과 (각 부서별 평균연봉보다 작은 사원 출력)
E_NAME DEPTNO SAL
------------------------------------------
구르미 D01 500
바나나 D01 700
토마토 D02 1000
부르릉 D03 300
# EXISTS 서브쿼리
SQL> SELECT A.E_NAME, A.DEPTNO, A.SAL
FROM EMP A
WHERE EXISTS (SELECT 1 FROM DEPT X
WHERE X.DEPTNO = A.DEPTNO
AND X.AVGSAL BETWEEN '1000' AND '1500');
# 실행결과 (부서의 평균연봉이 1000과 1500 사이인 부서의 모든사원 출력)
(D05 부서에는 두명이 전부이다. 그 부서의 평균연봉은 3500/2 = 1750 이다.)
E_NAME DEPTNO SAL
------------------------------------------
쿵쿵쿵 D05 3000
두두두 D05 500
붕붕붕 D06 1000
쿵쾅쾅 D06 1700
슝슝슝 D06 1500
...
244개의 행이 검색되었습니다.
728x90