1. 서브쿼리(Subquery)란?
- 쿼리 구문 안에 또 다시 쿼리 구문이 포함되어 있는 형태
- Group by 절을 제외한 쿼리구문에 사용 가능
- 서브쿼리 유형 : 단일행 서브쿼리(단일행 비교연산자), 다중행 서브쿼리 (다중행 비교연산자)
단일컬럼 서브쿼리(비쌍 비교), 다중컬럼 서브쿼리 (쌍 비교)
=> 단일행 서브쿼리(단일컬럼 / 다중컬럼), 다중행 서브쿼리(단일컬럼 / 다중컬럼) 총 4가지 유형 있음
< 서브쿼리 문법 >
- Subquery(inner query)를 먼저 실행하여 그 결과를 main query(outer query)에 사용함.
- 서브쿼리는 괄호로 묶어서 작성한다.
- where절 또는 having절에 사용된 경우 가독성을 위해 연산자의 오른쪽에 배치한다.
ex)
Davies란 직원보다 나중에 입사한 사원을 출력하는 구문을 작성하시오.
SELECT last_name, hire_date
FROM employees
WHERE hire_date > (SELECT hire_date
FROM employees
WHERE last_name = 'Davies');
단일 행 서브쿼리
- 서브쿼리로부터 메인쿼리로 한 행만 반환되는 유형
- 단일행 서브쿼리인 경우 메인쿼리에 단일행 비교연산자를 사용해야함. ( =, >, >=, <, <=, <> )
ex) 단일 컬럼
SELECT last_name, salary
FROM employees
WHERE salary >
(SELECT salary
FROM employees
WHERE last_name = 'Abel');
SELECT last_name, job_id, salary
FROM employees
WHERE salary = (SELECT MIN(salary) FROM employees);
다중 행 서브쿼리
- 서브쿼리로부터 메인쿼리로 두 개 이상의 행을 반환되는 유형
- 다중행 서브쿼리인 경우 메인쿼리에 다중행 비교연산자를 사용해야함. ( IN, ANY, ALL )
연산자 | 의미 |
IN | - 리스트의 임의 멤버와 같음 - or 성격 |
ANY | - =, !=, >, <, <=, >= 연산자가 앞에 있어야 함 - 관계가 TRUE인 subquery의 결과 집합에 요소가 1개 이상 있는 경우 TRUE를 반환 - or 성격 |
ALL | - =, !=, >, <, <=, >= 연산자가 앞에 있어야 함 - Subquery 결과 집합의 모든 요소에 대한 관계가 TRUE인 경우 TRUE를 반환 - and 성격 |
ex) 단일 컬럼
SELECT employee_id, last_name, manager_id, department_id
FROM employees
WHERE manager_id IN (SELECT manager_id
FROM employees
WHERE employee_id IN (174, 141))
AND department_id IN (SELECT department_id
FROM employees
WHERE employee_id IN (174, 141))
AND employee_id NOT IN(174, 141);
SELECT employee_id, last_name, job_id, salary
FROM employees
WHERE salary < ANY (SELECT salary
FROM employees
WHERE job_id = 'IT_PROG')
AND job_id <> 'IT_PROG';
SELECT employee_id, last_name, job_id, salary
FROM employees
WHERE salary < ALL (SELECT salary
FROM employees
WHERE job_id = 'IT_PROG')
AND job_id <> 'IT_PROG';
ex) 다중 컬럼 서브쿼리
SELECT employee_id, first_name, department_id, salary
FROM employees
WHERE (department_id, salary) IN (SELECT department_id, min(salary)
FROM employees
GROUP BY department_id)
ORDER BY department_id;
- 서브쿼리로부터 반환되는 결과리스트에 null값이 있고, 메인쿼리에서 and의 성격을 가지는 not in, 또는 ALL 비교연산자를 사용하는 경우 메인쿼리의 결과 또한 null이 출력됨!!! 즉 결과값이 안나옴!!
SELECT last_name
FROM employees
WHERE employee_id NOT IN (SELECT manager_id
FROM employees);
=> 출력해보면 결과가 안나옴.
그러므로 not in, 또는 All 연산자를 사용할 때는 서브쿼리의 결과값에 null 값이 있어서는 안 됨!
아래와 같이 수정하면 잘 출력됨
SELECT last_name
FROM employees
WHERE employee_id NOT IN (SELECT manager_id
FROM employees
where manager_id is not null);
'5. DB > 4-1. MySQL DBMS' 카테고리의 다른 글
MySQL - [ 테이블에 선언된 제약조건 조회 ] (0) | 2022.05.10 |
---|---|
MySQL - [ TCL(트랜잭션 제어어) - commit / rollback ] (0) | 2022.05.04 |
MySQL - [ 그룹 함수 ] (0) | 2022.04.20 |
MySQL - [ 단일 행 함수 (변환 함수 / 제어 흐름 함수 / 시스템 정보 함수)] (0) | 2022.04.19 |
MySQL - [ 단일 행 함수 ( 숫자 함수 / 날짜 함수 ) ] (0) | 2022.04.18 |