SUBQUERY란?
- 쿼리를 보조해주는 기능의 쿼리를 서브쿼리라한다.
- 사원 'Abel' 보다 더 많은 급여를 받는 직원을 출력
- 현재 'Abel'의 급여를 알 수 없기 때문에 별도로 조회하는 것이 필요함.
- 외부에서 조건값을 얻어 올 수 있겠지만 오차를 줄이기 위해서는 데이터베이스 내부에서 바로 필요한 조건을 얻어오는 것이 좋음.
- 따라서 현재 시점의 'Abel' 급여값을 쿼리 내부에서 또 다른 쿼리가 조회할 수 있도록 서브쿼리 방식으로 얻어온다면 원하는 시점의 정확한 데이터를 얻을 수 있다.
- 순서 상 메인쿼리보다 서브쿼리가 먼저 실행된다.
SELECT employee_id, last_name, salary ← 메인쿼리, outer query
FROM employees
WHERE salary > (
SELECT salary
FROM employees ← 서브쿼리, inner query
WHERE last_name = 'Abel'
);
SELECT last_name, job_id, salary
FROM employees
WHERE salary =
(
SELECT MIN(salary)
FROM employees
);
- 서브쿼리 작성 시 서브쿼리의 연산 과정은 크게 중요하지 않음.
- 최종적으로 서브쿼리가 돌려주는 값의 데이터타입, 크기, 행과 열의 수가 적절하다면 동작에 전혀 문제가 없다.
- 사원들 중 최소급여와 동일한 급여를 받는 직원의 정보를 출력하는 쿼리를 작성
- 이 때 최소급여는 저장하고 있는 컬럼이 없으므로 직접 서브쿼리로 작성해야 한다.
SELECT employee_id, last_name, salary
FROM employees
WHERE salary = (
SELECT salary
FROM employees
WHERE last_name = 'King'
);
SQL Error [1242] [21000]: Subquery returns more than 1 row
- 'King'과 동일한 급여를 받는 직원들을 출력하는 서브쿼리이나 에러가 발생한다.
- 이유는 '=' 연산자는 조건값을 하나만 받을 수 있지만 다음 서브쿼리에서는 King이 두명이었기 때문에 행이 두개가 리턴되면서 메인쿼리가 값을 두개를 받게되어 오류가 발생하게 된다.
- 서브쿼리가 메인쿼리에서 처리할 수 있는 행만 출력할 수 있도록 조건을 적절히 조정해서 해결한다.
SELECT employee_id, last_name, salary
FROM employees
WHERE salary IN (
SELECT salary
FROM employees
WHERE last_name = 'King'
);
employee_id|last_name|salary |
-----------+---------+--------+
100|King |26510.00|
150|Tucker |11000.00|
156|King |11000.00|
여러개의 행데이터를 처리할 수 있는 연산자로는 'IN' 연산자가 있다.
SELECT employee_id, last_name, salary
FROM employees
WHERE salary IN (
SELECT last_name, salary
FROM employees
WHERE last_name = 'King'
);
SQL Error [1241] [21000]: Operand should contain 1 column(s)
- 서브쿼리 활용 시 서브쿼리가 출력하는 컬럼의 이름은 상관이 없으나 출력하는 컬럼의 수는 영향이 있다.
- 메인쿼리에서 하나의 컬럼으로 비교하도록 작성했다면 서브쿼리도 동일한 구성의 컬럼으로 값을 구성하여 출력하도록 해야 한다.
SELECT employee_id, last_name
FROM employees
WHERE employee_id IN (
SELECT DISTINCT manager_id
FROM employees
WHERE last_name = 'Abel'
);
employee_id|last_name|
-----------+---------+
149|Zlotkey |
서브쿼리를 활용하여 사원들의 매니저로 근무하는 직원들의 employee_id, last_name을 출력하시오(JOIN X)
SELECT employee_id, last_name
FROM employees
WHERE employee_id IN (
SELECT DISTINCT manager_id
FROM employees
);
employee_id|last_name|
-----------+---------+
100|King |
101|Kochhar |
102|De Haan |
103|Hunold |
부서별로 사원의 최소 급여가 50번 부서의 최소급여보다 더 많은 부서의 department_id 값과 해당 부서의 최소급여 금액을 출력하시오.
SELECT department_id, MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary) >
( SELECT MIN(salary)
FROM employees
WHERE department_id = 50
);
department_id|MIN(salary)|
-------------+-----------+
| 7700.00|
10| 4840.00|
20| 6600.00|
- 서브쿼리는 리터럴 값이 들어갈 수 있는 위치라면 대부분 사용가능하다.
- HAVING절에서도 사용 가능
'DB > MySQL' 카테고리의 다른 글
[Mysql] 서브쿼리 예제문제 (1) | 2023.09.18 |
---|---|
[Mysql] 인라인뷰, 조건의 쌍비교 방식 (2) | 2023.09.16 |
[Mysql] 통계와 관련된 그룹 함수 (0) | 2023.09.16 |
[Mysql] 그룹함수와 그룹화 (0) | 2023.09.16 |
[Mysql] 제어 흐름 함수 (0) | 2023.09.16 |