본문 바로가기
MySQL

subquery 서브 쿼리

by 개발자공부 2024. 6. 13.

서브쿼리(subquery)

SQL 문장 내에서 다른 SQL 쿼리를 내포하는 구문이다.

보통 소괄호( ) 안에 작성되며, 메인 쿼리(main query) 또는 외부 쿼리(outer query) 라고 하는 더 큰 SQL 쿼리의 일부로 존재한다. 서브쿼리는 메인 쿼리에 의해 반환된 데이터를 기반으로 추가적인 조건을 적용하거나 메인 쿼리의 조건을 정의하는데 사용된다.

 

문법 형태 

select *
from reservation
where name in( select name from customer where address = '서울' );

 

서브쿼리 사용하는 이유

1. 복잡성 감소 : 복잡한 쿼리를 더 작고 관리하기 쉬운 부분으로 나누어 처리할 수 있다.

2. 재사용성 : 같은 서브쿼리를 여러 쿼리에서 재사용할 수 있어 코드의 중복을 줄이고 유지 보수를 용이하게 한다.

3. 명확성 : 데이터의 특정 부분에 대해 명확한 조건을 설정할 수 있으며, 읽기 쉽고 이해하기 쉬운 쿼리를 작성할 수 있다.

 

서브쿼리 종류

서브쿼리는 쿼리의 위치가 어디에 있느냐에 따라서 세 가지 종류로 나눌 수 있다.

1. 중첩 서브 쿼리(Nested Subquery) : WHERE절에 사용하는 서브 쿼리. - 변수처럼 사용.

2. 인라인 뷰(Inline View) : FROM절에 사용하는 서브 쿼리. - 테이블처럼 사용.

3. 스칼라 서브 쿼리(Scalar Subquery) : SELECT절에 사용하는 서브 쿼리.

* 수행 속도가 느릴 수 있기 때문에 가능한 지양하는 것이 좋다.


중첩 서브 쿼리(Nested Subquery) - WHERE 절에 사용

WHERE 절에 사용되어 외부 쿼리에 필터 조건을 제공한다. 서브 쿼리의 결과를 이용하여 메인 쿼리의 결과가 결정되는 방식으로 작동한다.

 

● 시나리오 쿼리 1 - employees 테이블에서 manager 직원만 출력하시오.

-- 사전 데이터 확인 
select * 
from employees;

select * 
from dept_manager
where  to_date = '9999-01-01';

-- 직원 테이블에 매니저인 사원들을 출력 하자. !! 
select * 
from employees
where emp_no in (select emp_no
				from dept_manager
				where to_date = '9999-01-01')

 

인라인 뷰(Inline View) - FROM 절에 사용

임시적인 테이블을 생성하여 메인 쿼리에 참조한다. 이 방식은 복잡한 데이터 집계나 여러 단계의 데이터 변환을 필요로 하는 조회에서 유용하게 사용된다.

 

● 시나리오 쿼리 2 - 현재 매니저들에 평균 연봉 구하기

-- From 절에 사용하는 인라인 뷰 
-- 현재 다니고 있는 매니저들에 평균 연봉 구하기. 

select * from dept_manager where to_date = '9999-01-01';
select * from salaries where emp_no = 10001;

-- 한 직원에 평균 연봉, emp_no 그룹바이 처리 
select emp_no, avg(salary) as 평균연봉
from salaries as s 
group by emp_no;
 
-- 조건 추가 
-- 인라인뷰를 사용했던 개념 
select emp_no, 평균연봉
from (select emp_no, avg(salary) as 평균연봉
		from salaries as s 
		group by emp_no) as avg_salary
where emp_no = '10001';

-- 인라인 뷰, 중첩 서브쿼리를 동시 사용 
select emp_no, 평균연봉
from (select emp_no, avg(salary) as 평균연봉
		from salaries as s 
		group by emp_no) as avg_salary
where emp_no in (select emp_no 
				from dept_manager
				where to_date = '9999-01-01');

 

위 쿼리는 개념 학습을 위한 것이다. 사실 위 결과 집합을 얻기 위해서는 아래와 같은 쿼리가 훨씬 더 효율을 높일 수 있다.

select s.emp_no, AVG(s.salary) as '평균연봉'
from salaries as s 
inner join dept_manager as d 
		on s.emp_no = d.emp_no and d.to_date = '9999-01-01' 
group by s.emp_no;

 

'MySQL' 카테고리의 다른 글

DML,DDL,DCL  (0) 2024.06.21
Function  (0) 2024.06.11
JOIN  (0) 2024.06.11
INDEX  (0) 2024.06.11
KEY  (0) 2024.06.11