반응형
절 | 서브쿼리 사용 가능 | 서브쿼리 이름 |
SELECT | O | Scalar Subquery |
FROM | O | In line view |
WHERE | O | Subquery |
GROUP BY | X | X |
HAVING | O | Scalar Subquery |
ORDER BY | O | Scalar Subquery |
문제 418. 토탈월급을 출력하시오.
SELECT SUM(sal)
FROM emp;
문제 419. 이름, 월급, 토탈월급을 출력하시오.
SELECT ename, sal, SUM(sal) OVER()
FROM emp;
문제 420. 이름, 월급, 토탈 월급을 출력하는데, SELECT절의 서브쿼리인 스칼라 서브쿼리를 이용해서 출력하시오.
SELECT ename, sal, (SELECT SUM(sal) FROM emp) AS 토탈월급
FROM emp;
* SELECT절의 서브쿼리인 스칼라 서브쿼리는 emp 테이블의 건수만큼 반복되면서 수행됨.(WHERE절 안썼을 경우)
cf. WHERE절 쓸 경우 WHERE절에 의해 걸러진 행 갯수만큼 반복 수행.
=> 가져오는 테이블의 건수만큼 서브쿼리가 수행되므로 속도가 느려짐. 악성SQL. 튜닝의 필요성
문제 421. 직업이 SALESMAN인 사원들의 토탈월급을 출력하시오.
SELECT SUM(sal)
FROM emp
where job = 'SALESMAN';
문제 422. 이름, 월급, 직업이 SALESMAN인 사원들의 토탈월급을 출력하시오.
전체 직원 이름, 월급 옆에 세일즈맨 월급 총합 쭉 출력하면 됨. (본인 직업이 뭐든간)
SELECT ename, sal, (SELECT SUM(sal) FROM emp WHERE job = 'SALESMAN') AS s_tot
FROM emp;
문제 423. 이름, 월급, 직업이 SALESAMAN인 사원들의 토탈월급, 직업이 SALESAMAN인 사원들의 최대월급, 직업이 SALESAMAN인 사원들의 최소월급을 출력하시오.
SELECT ename, sal,
(SELECT SUM(sal) FROM emp WHERE JOB = 'SALESMAN') 토탈월급,
(SELECT MAX(sal) FROM emp WHERE JOB = 'SALESMAN') 최대월급,
(SELECT MIN(sal) FROM emp WHERE JOB = 'SALESMAN') 최소월급
FROM emp;
위의 SQL의 문제점은 emp 테이블의 건수만큼 스칼라 서브쿼리의 select문이 반복된다는 것.
(emp 테이블을 각각 3번 액세스)
흔히 잘못 접근하는 예
1. 일단 총합, 최댓값, 최솟값을 한 번에 출력하는 쿼리를 작성한다.
SELECT SUM(sal), MAX(sal), MIN(sal)
FROM emp
WHERE JOB = 'SALESMAN';
이렇게 하면 한번에 세가지 값이 나옴.
2. 위의 쿼리를 메인쿼리의 SELECT절에 스칼라 서브쿼리로 한번에 넣음.
SELECT ename, sal,
(SELECT SUM(sal), MAX(sal), MIN(sal) -- 1단계에서 작성한 부분
FROM emp
WHERE job = 'SALESMAN')
FROM emp;
오류 메세지 출력
ORA-00913: 값의 수가 너무 많습니다
00913. 00000 - "too many values"
스칼라 서브쿼리의 특징
: 하나의 값만 출력할 수 있음.
한번에 총합, 최대, 최솟값을 다 출력하려고 하기 때문에 오류 발생.
즉 423번 맨 처음처럼 스칼라 서브쿼리를 하나씩 작성해 콤마(,)로 연결해야함.
문제 426. 이름, 월급, 부서위치를 출력하시오.
EQUI JOIN 방식
SELECT E.ename, E.sal, D.loc
FROM emp E, dept D
WHERE E.deptno = D.deptno;
Scalar Subquery 방식
SELECT ename, sal, (SELECT loc FROM dept D WHERE E.deptno = D.deptno) AS 부서위치
FROM emp E;
문제 427. 부서번호, 이름, 월급, 자기가 속한 부서번호의 평균월급을 출력하시오.
(scalar subquery로)
SELECT empno, ename, sal,
(SELECT AVG(sal)
FROM emp S
WHERE S.deptno = E.deptno) 부서평균
FROM emp E;
수행순서
1. 메인쿼리 FROM
2. 메인쿼리 SELECT
3. 2의 행 하나하나마다 서브쿼리 WHERE
4. 2의 행 하나하나마다 서브쿼리 SELECT
'Oracle DBA > SQL' 카테고리의 다른 글
079 데이터 수정하기(UPDATE) (0) | 2023.07.06 |
---|---|
078 데이터 입력하기(INSERT) (0) | 2023.07.06 |
076 서브 쿼리 사용하기 6 (FROM절의 서브 쿼리) (0) | 2023.07.05 |
075 서브 쿼리 사용하기 5(HAVING절의 서브 쿼리) (0) | 2023.07.05 |
074 서브 쿼리 사용하기 4(EXISTS와 NOT EXISTS) (0) | 2023.07.05 |