서브쿼리(Subquery)
- 서브쿼리(subquery)는 하나의 SQL문에 포함되어 있는 또 다른 SQL 문을 말합니다.
- 서브쿼리(subquery)를 포함하고 있는 쿼리(query)를 외부쿼리(outer query)라고 부르며, 서브쿼리(subquery)는 내부쿼리(inner query)라고도 부릅니다.
- 서브쿼리는 다음과 같이 괄호()로 감싸져서 사용됩니다.
서브쿼리(Subquery)를 사용할 때는 성능 저하를 유의해야 하며, 가능하다면 JOIN을 사용하는 것이 효율적일 수 있습니다. 서브쿼리는 복잡한 데이터 처리 요구사항에 유용하지만, 쿼리의 복잡성과 실행 시간이 증가할 수 있습니다.
서브쿼리?
id가 '30'인 임직원 보다 입사일이 빠른 임직원의 id, 입사일(enter_date)을 알고 싶다고 가정합니다.
1. id가 '30'인 임직원의 입사일
SELECT enter_date FROM employee WHERE id = '30';
+-------------------+
| enter_date |
+-------------------+
| 2023-05-30 |
+-------------------+
2. '2023-05-30' 보다 입사일이 빠른 임직원의 id, 입사일(enter_date)을 알고 싶다.
SELECT id, enter_date FROM employee WHERE enter_date < '2023-05-30';
1번과 2번 처럼 진행하게 된다면, 원하는 결과를 한 쿼리에서 얻을 수 없다.
Subquery 예제
서브쿼리(subquery)를 알아봅시다.
-- main query
SELECT id, enter_date FROM employee WHERE enter_date < (
-- subquery
SELECT enter_date FROM employee WHERE id = '30'
);
-- 서브쿼리(subquery) 실행순서 subquery 실행 => main query 실행
- subquery(inner query): SELECT, INSERT, UPDATE, DELETE에 포함된 쿼리
- main query(outer query): subquery를 포함하는 쿼리
Subquery 장점
- 쿼리를 구조화시키므로, 쿼리의 가 부분을 명확히 구분할 수 있게 해줍니다.
- JOIN이나 UNION과 같은 동작을 수행할 수 있는 또 다른 방법을 제공합니다.
- 복잡한 JOIN이나 UNION 보다 가독성이 좋습니다.
위치에 따른 명칭
스칼라 서브쿼리 (Scalar Subquery)
스칼라 서브쿼리는 단일 값을 반환하는 서브쿼리로, 하나의 컬럼 값처럼 SELECT 문의 컬럼 리스트에서 사용됩니다. 이 서브쿼리는 SELECT 절에서 하나의 값을 반환해야 하며, 그 값은 상위 쿼리의 다른 컬럼 값과 함께 결과로 표시됩니다.
SELECT name, salary, (
SELECT AVG(salary)
FROM employee e2
WHERE e2.dept_id = e1.dept_id
) AS avg_salary
FROM employee e1;
이 예제에서 스칼라 서브쿼리는 각 직원이 속한 부서의 평균 급여를 계산합니다.
인라인 뷰 (Inline View)
인라인 뷰는 SELECT 문 내부에 위치하는 서브쿼리로, 하나의 테이블처럼 FROM 절에서 사용됩니다. 인라인 뷰를 사용하면 복잡한 데이터 집합을 생성하고, 이를 마치 임시 테이블처럼 사용하여 데이터를 조회할 수 있습니다.
SELECT e.name, e.salary
FROM (
SELECT name, MAX(salary) AS salary
FROM employee
WHERE dept_id = 1
GROUP BY name
) AS e;
이 예제에서 인라인 뷰는 dept_id가 1인 직원들 중에서 각 이름별로 가장 높은 급여를 계산합니다.
인라인 뷰 (Inline View) 활용
임시 테이블처럼 복잡한 데이터 집합을 생성하고 조회할 수 있습니다.
SELECT e.name, d.avg_dept_salary
FROM employee e
INNER JOIN (
SELECT dept_id, AVG(salary) AS avg_dept_salary
FROM employee
GROUP BY dept_id
) AS d ON e.dept_id = d.dept_id
WHERE e.salary > d.avg_dept_salary;
이 예제에서는 각 부서의 평균 급여를 계산한 후, 해당 부서의 평균보다 높은 급여를 받는 직원들을 찾습니다. 인라인 뷰를 통해 각 부서의 평균 급여를 계산하고, 이 결과를 메인 쿼리에서 사용하여 조건에 맞는 직원을 선택합니다.
일반 서브쿼리 (General Subquery)
일반 서브쿼리는 WHERE 절에서 사용되며, 조건을 만족하는 특정 값을 반환합니다. 이 서브쿼리는 상위 쿼리의 조건절에서 하나의 값(상수)으로 사용되어, 서브쿼리의 결과에 따라 다른 행을 선택할 수 있게 합니다.
SELECT name, salary
FROM employee
WHERE salary > (
SELECT AVG(salary)
FROM employee
WHERE dept_id = 1
);
이 예제에서 일반 서브쿼리는 dept_id가 1인 직원들의 평균 급여를 계산하며, 메인 쿼리는 이 평균보다 높은 급여를 받는 직원들을 선택합니다.
일반 서브쿼리 (General Subquery)
데이터베이스 내 다른 위치의 데이터를 참조하여 조건을 동적으로 적용할 때 유용합니다.
SELECT name, salary
FROM employee e1
WHERE EXISTS (
SELECT 1
FROM employee e2
WHERE e2.dept_id = e1.dept_id
AND e2.salary > e1.salary
);
이 예제에서는 자신보다 높은 급여를 받는 직원이 같은 부서에 존재하는 직원들을 선택합니다. EXISTS 키워드를 사용한 서브쿼리는 조건을 만족하는 행이 존재하는지를 검사하여, 참인 경우에만 상위 쿼리의 해당 행을 선택합니다.
SELECT문과 서브쿼리(subquery) 안다면,
INSERT 문과 UPDATE 문, DELETE 문에도 적용할 수 있다.
'데이터베이스 (DB)' 카테고리의 다른 글
원온원(1on1) 미팅 관리 시스템: 설계 및 구현 가이드 (0) | 2024.11.07 |
---|---|
테이블 정보 조회하기, Table Description 쿼리 (0) | 2024.10.25 |
저장 프로시저 내용 검색하기 (1) | 2024.10.08 |
[SQL Server] MSSQL로 직장 근무 연수 구하기 (0) | 2024.05.13 |
Firebase 프로젝트 진행하기 (0) | 2024.05.06 |