서브 쿼리(subquery)
SQL 문장 내에서 다른 SQL 쿼리를 내포하는 구문
: 서브쿼리는 보통 소괄호 ( ) 안에 작성되며, 메인 쿼리 (main query) 또는 외부 쿼리 (outer query) 라고 하는 더 큰 SQL 쿼리의 일부로 존재한다.
서브쿼리는 메인 쿼리에 의해 반환된 데이터를 기반으로 추가적인 조건을 적용하거나, 메인 쿼리의 조건을 정의하는 데 사용된다.
- 서브쿼리 문법의 형태
select *
from reservation
where name in( select name from customer where address ='서울' );
서브쿼리를 사용하는 이유
- 복잡성 감소 : 복잡한 쿼리를 더 작고 관리하기 쉬운 부분으로 나누어 처리할 수 있다.
- 재사용성 : 같은 서브쿼리를 여러 쿼리에서 재사용할 수 있어, 코드의 중복을 줄이고 유지 보수가 용이해진다.
- 명확성 : 데이터의 특정 부분에 대해 명확한 조건을 설정할 수 있으며, 읽기 쉽고 이해하기 쉬운 쿼리 작성이 가능하다.
서브쿼리의 종류
서브쿼리는 쿼리의 위치가 어디에 있느냐에 따라, 세 가지 종류로 나눌 수 있다.
(1) 중첩 서브 쿼리 (Nested Subquery) : WHERE 절에 사용하는 서브쿼리.
(2) 인라인 뷰 (Inline View) : FROM 절에 사용하는 서브쿼리.
(3) 스칼라 서브 쿼리 (Scalar Subquery) : SELECT 절에 사용하는 서브쿼리.
(1) 중첩 서브 쿼리 (Nested Subquery) - WHERE 절에 사용
WHERE 절에 사용되어 외부 쿼리에 필터 조건을 제공한다.
서브쿼리의 결과를 이용하여 메인쿼리의 결과가 결정되는 방식으로 작동한다.
employees 테이블에서 manager인 직원만 출력 하세요.
select *
from employees
where emp_no in (select emp_no
from dept_manager
where to_date = '9999-01-01')
(2) 인라인 뷰 (Inline View) - FROM 절에 사용
FROM 절에 사용되는 서브 쿼리로, 임시적인 테이블을 생성하여 메인 쿼리에서 참조한다.
이 방식은 복잡한 데이터 집계나 여러 단계의 데이터 변환을 필요로 하는 조회에서 유용하게 사용된다.
현재 매니저들의 평균 연봉 구하기
-- from 절에 사용하는 인라인 뷰
-- 현재 재직 중인 매니저들의 평균 연봉 구하기
select * from dept_manager where to_date = '9999-01-01'; -- 재직 중인 매니저 조회
select * from salaries where emp_no = 10001; -- 10001번 사원의 연봉 조회
-- 한 직원의 평균 연봉, emp_no : group by 처리
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');
-- 위와 같은 결과 집합을 INNER JOIN을 활용해 만들어 보자.
select s.emp_no, avg(s.salary) as 평균연봉
from salaries s
join dept_manager d on s.emp_no = d.emp_no
where d.to_date = '9999-01-01'
group by s.emp_no;
select s.emp_no, avg(s.salary) as 평균연봉
from salaries s
join dept_manager d on s.emp_no = d.emp_no and d.to_date = '9999-01-01' -- on 절에 조건 추가 가능 !
group by s.emp_no;
select * from dept_manager;
select * from salaries;
(3) 스칼라 서브쿼리 (Scalar Subquery) - SELECT 절에 사용
Scalar Subquery는 SELECT 절에서 사용되며 단일 값을 반환한다.이 값은 메인 쿼리의 다른 컴럼과 함꼐 출력될 수 있다.스칼라 서브 쿼리는 각 결과 행에 대해 계산되어 해당 행의 결과에 포함된다.
단, 수행속도가 가장 느릴 수 있기 때문에 가능한 지양하는 것이 좋다.
각 직원의 평균 연봉 구하기-- 스칼라 서브 쿼리 사용해보기 : 각 직원의 평균 연봉 구하기 select emp_no as outer_emp_no, (select avg(salary) from salaries where emp_no = outer_emp_no) as 평균연봉 from employees;
스칼라 서브쿼리가 각 행에 대해 별도로 실행되기 때문에 메인 쿼리가 처리해야 할 행의 수가 많을 경우, 전체 쿼리의 실행 시간이 상당히 증가할 수 있다.
따라서 다음과 같은 상황에서는 스칼라 서브쿼리의 사용을 재고해야 할 수 있다.
- 데이터 양이 많은 경우 : 대량의 데이터를 처리할 때는 스칼라 서브쿼리가 각 행마다 실행되어 성능 저하를 일으킬 수 있다.
- 더 효율적인 대안이 가능한 경우 : 때로는 조인(JOIN) 이나 임시 테이블, 또는 다른 SQL 최적화 기법을 사용하여 더 효율적으로 동일한 결과를 얻을 수 있다.
스칼라 서브쿼리를 사용할 때는 성능을 주의 깊게 고려하고, 필요하다면 쿼리 플랜을 검토하거나 다른 방법을 모색하는 것이 좋다.
'MySQL' 카테고리의 다른 글
제 2정규화(Second Normal Form, 2NF) (0) | 2024.07.08 |
---|---|
제 1정규화(First Normal Form, 1NF) (0) | 2024.06.13 |
쇼핑몰 서비스의 DB 구축 (1) | 2024.06.12 |
블로그 서비스의 DB 구축 (0) | 2024.06.12 |
SELF JOIN (0) | 2024.06.12 |