728x90
SUBQUERY
@2024.05.03
SUBQUERY
💡
하나의 SQL 질의문 속에 다른 SQL 질의문이 포함되어 있는 형태
Single-Row SUBQUERY
💡
SubQuery의 결과가 한 행(ROW)인 경우 사용
- =, >, >=, <, <=, <> 연산자 사용
- 예시
- 이름으로 정렬했을 때 첫 번째 나오는 이름의 이름, 급여, 부서 번호 출력하라.
SELECT ename, sal, deptno FROM emp WHERE ename = (SELECT MIN(ename) FROM emp);
- 사원의 평균 급여보다 작은 급여를 받는 사원의 이름과 급여를 출력하라.
SELECT ename, sal FROM emp WHERE sal < (SELECT AVG(sal) From emp);
- 부서 이름이 SALES인 부서의 사원 이름과 부서 번호를 출력하라.
SELECT ename, deptno FROM emp WHERE deptno = (SELECT ename FROM emp WHERE dname = 'SALSE');
Multi-Row SUBQUERY
💡
SubQuery의 결과가 두 행(ROW) 이상인 경우 사용
- ANY, ALL, IN, EXIST 등 연산자 사용
- 부서별 이름 순서가 첫 번째 사원 이름, 급여, 부서 번호를 출력하라.
-- 잘못된 문장 SELECT ename, sal, deptno FROM emp WHERE ename = (SELECT MIN(ename) FROM emp GROUP BY deptno);
- 부서별로 최소 ename 값을 갖는 사원이 여러 명 존재할 가능성이 있다!
- 따라서 서브 쿼리가 여러 행을 반환하므로, = 연산자와 비교할 수 없다!
-- 위에 잘못된 문장의 올바른 예 SELECT ename, sal, deptno FROM emp WHERE ename IN (SELECT MIN(deptno) FROM emp GROUP BY deptno);
- IN
- 다수의 비교 값 중 하나라도 만족하면 True
- 모든 조건에 OR 연산을 수행한 것과 동일
-- sal == 950 or 3000 or 1250 SELECT * FROM emp Where sal IN(950, 3000, 1250);
- ANY
- 다수의 비교 값 중 하나라도 만족하면 True
- 모든 조건에 OR 연산을 수행한 것과 동일
- IN과 다른 점은 비교 연산자를 사용할 수 있다는 점
- 만약 =을 사용할 때 서브 쿼리의 여러 개라면 오류 발생
-- 950보다 큰 값을 모두 출력하라 SELECT * FROM emp Where sal > ANY(950, 3000, 1250);
- ALL
- 전체 값을 비교하여 모두 만족하면 True
- 모든 조건에 AND 연산을 수행한 것과 동일
-- 모두 다 같을수는 없기에 False SELECT * FROM emp Where sal = ALL(950, 3000, 1250); -- 3000보다 큰 값만 출력 SELECT * FROM emp Where sal > ALL(950, 3000, 1250);
Correlated Query
💡
메인 쿼리의 결과에 따라 서브 쿼리가 실행되는 서브 쿼리 형태로 상호 연관 서브 쿼리라고도 불린다.
- Outer Query와 Inner Query가 서로 연관되어 있다.
- 실행 과정
- Outer Query의 한 행을 얻는다.
- 해당 행을 가지고 Inner Query를 계산
- 계산 결과를 이용하여 Outer Query의 WHERE 절을 평가
- 결과가 참이면 해당 행을 결과에 포함시킨다.
- 예시
- 사원의 이름, 급여, 부서 번호를 출력하라.
단, 사원의 급여가 그 사원이 속한 부서의 평균 급여보다 큰 경우에만 출력하라.
SELECT A.ename, A.sal, A.deptno FROM emp A WHERE A.sal > (SELECT AVG(B.sal) FROM emp B WHERE A.deptno = B.deptno);
- 각 부서별로 최고 급여를 받는 사원을 출력하라.
-- 방법 1 SELECT deptno, empno, ename, sal FROM emp WhERE (deptno, sal) IN (SELECT deptno, MAX(sal) FROM emp Group BY deptno);
-- 방법 2 SELECT A.deptno, A.empno, A.ename, A.sal /* 서브 쿼리 : emp 테이블을 사용하여 각 부서의 최고 급여을 계산 - C라는 별칭 사용 */ FROM emp A, (SELECT B.deptno, MAX(B.sal) AS msal FROM emp B GROUP BY deptno) C /* 부서 번호와 급여가 서브쿼리에서 계산된 최고 급여와 일치하는 행만 선택 */ WHERE A.deptno = C.deptno AND A.sal = C.msal;
- 사원의 이름, 급여, 부서 번호를 출력하라.
Set Operator
💡
set 연산자는 두 개 이상의 쿼리 결과를 결합하는 데 사용
UNION (A ∪ B)

💡
두 개의 쿼리 결과를 결합하고, 중복된 행을 제거
SELECT * FROM A UNION SELECT * FROM B;
UNION ALL (A ∪ B)

💡
두 개의 쿼리 결과를 결합하나, 중복된 행을 제거하지 않는다.
SELECT * FROM A UNION ALL SELECT * FROM B;
INTERSECT (A ∩ B)

💡
두 개의 쿼리 결과에서 공통된 행만을 선택하며 해당 키워드는 MySQL에서 지원하지 않는다.
SELECT A.name FROM A, B WHERE A.name = B.name;
MINUS(=EXCEPT)(A - B)

💡
첫 번째 쿼리 결과에서 두 번째 쿼리 결과에 없는 행 선택하며, 해당 키워드는 MySQL에서 지원하지 않는다.
SELECT A.name FROM A WHERE A.name not in (SELECT B.name FROM B);
RANK() 함수
💡
MYSQL 8.0버전부터 도입된 함수로, 주어진 집합 내에서 특정 값의 순위를 지정하는 함수다.
- 예시
- 직원의 급여와 이름을 선택하고, 급여를 기준으로 내림차순으로 정렬된 순서대로 각 직원의 순위를 지정
SELECT sal, ename, RANK() OVER(ORDER BY sal DESC) AS ranking FROM emp;
< 쿼리 실행 전 >
empno ename sal 1001 Alice 5000 1002 Bob 4000 1003 Charlie 4500 1004 David 5500 < 쿼리 실행 후 >
sal ename ranking 5500 David 1 5000 Alice 2 4500 Charlie 3 4000 Bob 4
728x90
'MYSQL' 카테고리의 다른 글
CREATE / INSERT 절 (0) | 2024.05.30 |
---|---|
MYSQL 명령어 총 정리 (0) | 2024.05.26 |
조인 (0) | 2024.05.07 |
GROUP BY (0) | 2024.05.05 |
형 변환 (0) | 2024.05.05 |