일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
- java
- jsp
- frontend
- 문자열
- HTML
- web
- oracle
- SQL
- 코딩
- It
- Programming
- 오라클
- PL/SQL
- Method
- 자바
- 함수
- 프로그래밍
- 서블릿
- Database
- 자바스크립트
- function
- String
- 웹
- 파이썬
- 프론트엔드
- JavaScript
- 데이터베이스
- 메소드
- Servlet
- Python
- Today
- Total
Untitled_Blue
[SQL] 쿼리 안에 또 다른 쿼리?! - 서브쿼리 (Sub Query) 본문
안녕하세요. 이번 글은 서브쿼리에 대한 설명입니다.
- 서브쿼리(Sub Query)란?
- SQL문을 실행할 때 필요한 데이터를 추가로 조회하고자 할때 select문을 통한 이중 쿼리문
- 보다 더 자세한 조건을 기반으로 데이터를 검색할 때 많이 사용된다.
SELECT [칼럼명1], [칼럼명2] …
FROM [테이블명]
WHERE [조건컬럼명] (연산자) (
SELECT [조건칼럼명]
FROM [테이블명]
WHERE [조건식]
);
상단 코드는 서브쿼리를 사용하는 전반적인 구조이다. 자세한 조건을 기반으로 데이터를 검색하는 만큼 주로 where 문 안에서 제일 많이 사용된다. 이번 글은 예제를 실습하는 방식을 위주로 진행할 예정이다. 필요한 문법에 대한 설명도 추가할 것이다.
+ 서브쿼리는 단일 행과 다중 행으로 구성되어 있는데 상단의 구조는 단일 행 서브쿼리에 해당된다.
- EMP테이블에서 turner의 직책과 같은 직책인 사원들 검색
select ENAME, JOB from EMP where JOB = (select JOB from EMP where ENAME = 'TURNER');
다음 쿼리는 EMP 테이블에서 사원명과 직책을 조회하는데 직책이 같은 테이블 내 TURNER 사원과 같은 직책인 사람들만 조회하라는 뜻을 가지고 있다. 해당 쿼리를 실행해보면 위와 같은 결과가 보일 것이다.
- EMP 테이블에서 CLARK 사원보다 많은 또는 적은 급여를 받는 사원들 검색
select ENAME, JOB, SAL from EMP where SAL > (select SAL from EMP where ENAME = 'CLARK');
select ENAME, JOB, SAL from EMP where SAL < (select SAL from EMP where ENAME = 'CLARK');
다음 쿼리문은 EMP 테이블에서 사원명, 직책과 급여를 조회하는데 급여가 CLARK 사원보다 많이 또는 적게 받는 사원들만 출력하라는 뜻을 가지고 있다. 상단의 두 쿼리문을 실행해보면 위와 같이 정상적으로 출력되었음을 확인할 수 있다.
- EMP 테이블에서 BLAKE 사원보다 먼저 또는 늦게 입사한 사원 목록 출력
select ENAME, HIREDATE from EMP where HIREDATE > (select HIREDATE from EMP where ENAME = 'BLAKE');
select ENAME, HIREDATE from EMP where HIREDATE < (select HIREDATE from EMP where ENAME = 'BLAKE');
다음 쿼리문은 EMP 테이블에서 사원명과 입사날짜를 출력하는데 입사날짜가 BLAKE 사원보다 일찍 또는 늦게 입사한 사원들을 선별해서 출력하라는 뜻을 가지고 있다. 두 개의 쿼리문을 하나씩 실행해보면 위와 같은 결과를 확인할 수 있다.
- EMP 테이블에서 BLAKE 사원의 부사수인 사원 목록 출력
select ENAME, MGR from EMP where MGR = (select EMPNO from EMP where ENAME = 'BLAKE');
다음 쿼리문은 EMP 테이블에서 사원명과 사수의 사번을 출력하는데 사수의 사번이 BLAKE 사원의 사번과 같은 행만 선별해서 출력하라는 뜻을 가지고 있다. 쿼리문을 실행하면 위와 같이 BLAKE의 부사수 목록을 확인할 수 있다.
- 여러 개의 결과를 얻을 수 있는 다중행 서브쿼리 (Multiple-row Sub Query)
- 실행결과가 여러 개로 출력되는 서브쿼리
다중 행 연산자 | 설명 |
IN | 메인 쿼리의 비교 조건이 서브 쿼리의 비교 조건 결과와 하나라도 일치하면 참인 연산자 |
ANY, SOME | 메인 쿼리의 비교 조건이 서브 쿼리의 비교 조건 결과와 하나 이상 일치하면 참인 연산자 |
ALL | 메인 쿼리의 비교 조건이 서브 쿼리의 비교 조건 결과와 모두 일치하면 참인 연산자 |
EXISTS | 서브 쿼리의 비교 조건에 대한 결과가 하나라도 존재하면 참인 연산자 |
1) IN 연산자
select DEPTNO, MIN(SAL) from EMP group by DEPTNO;
select DEPTNO, ENAME, SAL from EMP where SAL IN (select MIN(SAL) from EMP group by DEPTNO);
다음 쿼리문은 EMP 테이블에서 부서번호, 사원명과 급여를 출력하는데 같은 테이블 내 부서번호 별로 가장 적은 급여와 동일한 급여를 받는 사원을 선별해서 출력하라는 뜻이다. 쿼리문을 실행해보면 각 부서번호별로 가장 적은 급여를 받는 사원이 출력됨을 확인할 수 있다. 여기서 group by가 나오는데 간단히 설명하자면 칼럼을 통해 그룹별로 묶은 데이터의 결과를 출력할 때 사용하는 SELECT 문법의 일부이다. 주로 그룹별 평균, 최소, 최대값을 구하는데 많이 사용된다.
2) ANY, SOME 연산자
select DEPTNO, ENAME, SAL from EMP where SAL < ANY (select SAL FROM EMP where ENAME = 'BLAKE');
다음 쿼리문은 EMP 테이블에서 부서번호, 사원명, 급여를 출력하는데 같은 테이블내 BLAKE의 급여보다 적은 급여를 받는 사원만을 출력하라는 뜻을 가지고 있다. 이를 출력하면 위와 같이 출력되었음을 확인할 수 있다. 참고로 BLAKE의 급여는 2850이다. SOME을 사용해도 같은 결과가 출력된다.
select SAL FROM EMP where ENAME = 'SMITH'; -- 800
select DEPTNO, ENAME, SAL from EMP where SAL < ANY (select SAL FROM EMP where ENAME = 'SMITH');
다음은 이전 쿼리문과 거의 비슷하게 SMITH 사원보다 적은 급여를 받는 사원만을 출력하라는 뜻을 가진 쿼리문인데 해당 쿼리를 실행해보면 아무 것도 나오지 않음을 확인할 수 있다. 왜냐하면 800보다 적게 받는 사원이 존재하지 않기 때문이다.
3) ALL
select SAL FROM EMP where DEPTNO = 30;
select DEPTNO, ENAME, SAL from EMP where SAL > ALL (select SAL FROM EMP where DEPTNO = 30);
다음 쿼리문은 EMP 테이블에서 부서번호, 사원명, 급여를 출력하는데 같은 테이블 내 부서번호가 30인 사람들의 급여 중에서 제일 많이 받는 사람보다 더 많은 급여를 받는 사원들을 선별해서 출력하라는 뜻을 가지고 있다. 해당 쿼리문을 실행해보면 위와 같은 결과를 확인할 수 있다. 이를 통해 ALL은 수많은 결과들 중에서도 비교 연산자를 기준으로 만족하는 결과가 존재하면 참인 연산자임을 알 수 있다.
4) EXISTS : 데이터의 존재여부를 확인하다.
select DEPTNO, ENAME, SAL from EMP where EXISTS (select * FROM EMP where DEPT.DEPTNO = EMP.DEPTNO);
다음 쿼리문은 EMP 테이블에서 부서번호, 사원명, 급여를 출력하는데 같은 테이블 내에서 DEPT 테이블의 부서번호와 EMP 테이블의 부서번호가 일치하는 행만 선별해서 출력하라는 뜻을 가지고 있다. 해당 쿼리문을 실행해보면 위와 같이 13개의 행이 출력되는 것을 확인할 수 있다. (사실상 전부 출력된 것이다..)
select DEPTNO, ENAME, SAL from EMP where EXISTS (select * FROM EMP where DEPTNO = 40);
다음 쿼리문을 실행해보면 아무 것도 출력되지 않는다. 애초에 부서번호에 40이 존재하지 않기 때문이다. 이를 통해 EXIST는 데이터의 존재 여부를 확인하는 연산자라는 점과 서브쿼리의 결과값이 하나 이상 존재하면 조건식이 모두 참 (모두 출력)이라는 점을 확인할 수 있다.
다음 글은 Group by에 대한 설명입니다. 감사합니다.
'Database > SQL' 카테고리의 다른 글
[SQL] DCL - COMMIT, ROLLBACK, GRANT, REVOKE (0) | 2023.06.20 |
---|---|
[SQL] 그룹별 데이터의 통계 - Group by and Having (0) | 2023.06.20 |
[SQL] DML - INSERT, UPDATE, DELETE (0) | 2023.05.30 |
[SQL] DDL - CREATE, ALTER, DROP (0) | 2023.05.29 |
[SQL] DECODE와 CASE 조건문 (0) | 2023.05.27 |