※ where 절에서는 그룹함수 불가 / having절 사용해야 함
셀프 조인 ex
○ ward 보다 늦게 입사한 사원 이름, 입사일
select e.ename, e.hiredate from employee e, employee f where f.ename='WARD' and e.hiredate>f.hiredate;
ENAME HIREDATE
-------------------- --------
JONES 81/04/02
MARTIN 81/09/28
BLAKE 81/05/01
CLARK 81/06/09
SCOTT 87/07/13
KING 81/11/17
TURNER 81/09/08
ADAMS 87/07/13
JAMES 81/12/03
FORD 81/12/03
MILLER 82/01/23
○ scott과 동일부서에 근무하는 사원 출력
select e.ename from employee e, employee f where f.ename='SCOTT' and f.dno=e.dno and e.ename<>'SCOTT';
ENAME
--------------------
SMITH
JONES
SCOTT
ADAMS
FORD
○ 관리자보다 먼저 입사한 모든 사원의 이름 입사일, 관리자이름 입사일
select e.ename, e.hiredate, f.ename, f.hiredate from employee e, employee f where e.manager=f.eno and f.hiredate>e.hiredate;
ENAME HIREDATE ENAME HIREDATE
-------------------- -------- -------------------- --------
ALLEN 81/02/20 BLAKE 81/05/01
WARD 81/02/22 BLAKE 81/05/01
JONES 81/04/02 KING 81/11/17
BLAKE 81/05/01 KING 81/11/17
CLARK 81/06/09 KING 81/11/17
SMITH 80/12/17 FORD 81/12/03
서브 쿼리
: 다른 쿼리문에 삽입된 select문
○ SCOTT보다 급여 많이 받는 사원
select ename, salary from employee where salary > (select salary from employee where ename='SCOTT');
ENAME SALARY
-------------------- ----------
KING 5000
○ 평균 급여 이상을 받는 사원수 조회
select count(*) from employee where salary > (select avg(salary) from employee);
COUNT(*)
----------
6
※ 테이블 만드는 방법
1. create table 테이블이름(컬럼명 타입, 컬럼명 타입,..)
2. 만들어진 테이블 구조 복사 - create table 테이블이름 as select * from employee where 1=0;
//데이터 가져오지 않고 구조만 가져옴
3. create table 테이블이름 as select * from employee;
※ 케이블에 자료 복사 : insert into emp_del select * from employee;
○ 평균 급여보다 많이 받는 사원 모두 삭제
delete from emp_del where salary > (select avg(salary) from emp_del);
6 행이 삭제되었습니다.
○ 최소 급여 받는 사원의 이름, 담당업무, 급여 출력
select ename, job, salary from employee where salary = (select min(salary) from employee);
ENAME JOB SALARY
-------------------- ------------------ ----------
SMITH CLERK 800
○ 30번 부서에서 최소 급여 구한 후, 부서별 최소 급여가 해당값보다 큰 부서 출력 (부서번호, 최소급여)
select dno, min(salary) from employee group by dno having min(salary) > (select min(salary) from employee where dno=30);
DNO MIN(SALARY)
---------- -----------
10 1300
다중행 서브쿼리
IN
ANY
SOME
ALL
EXISTS
○ IN : 서브쿼리의 결과들 중 하나라도 일치 시 리턴
ex. 부서별 최소급여 받는 사원번호, 이름
select eno, ename from employee where salary = (select min(salary) from employee group by dno);
//오류 // = 는 값 하나만 받기 때문에 여러 그룹 못 받음
select eno, ename from employee where salary in (select min(salary) from employee group by dno);
ENO ENAME
---------- --------------------
7369 SMITH
7900 JAMES
7934 MILLER
○ ANY : 서브쿼리가 반환하는 각각의 값 비교 => OR 과 유사
< ANY : 최대값보다 작음
> ANY : 최소값보다 큼
= ANY : IN과 동일
ex. 직급이 SALESMAN 아니면서 급여가 SALESMAN의 최댓값보다 낮은 사원
select eno, ename,salary from employee where job<>'SALESMAN' and salary < any(select salary from employee where job='SALESMAN');
ENO ENAME SALARY
---------- -------------------- ----------
7369 SMITH 800
7900 JAMES 950
7876 ADAMS 1100
7934 MILLER 1300
○ ALL : 조건 모두 만족하면 값 리턴
EX. 직급이 SALESMAN 아니면서 급여가 SALESMAN 최소값보다 낮은 사원 출력
select eno, ename, job, salary from employee where job<>'SALESMAN' and salary < all(select salary from employee where job='SALESMAN');
ENO ENAME JOB SALARY
---------- -------------------- ------------------ ----------
7876 ADAMS CLERK 1100
7900 JAMES CLERK 950
7369 SMITH CLERK 800
○ EXISTS : 서브쿼리의 결과 중 만족하는 값이 하나라도 존재하면 처리
=> 행의 존재 유무 확인, 그 외 작업 수행하지 않음 (고성능)
NOT EXISTS : NULL 있으면 TRUE 리턴
cf.
IN : 데이터들의 모든 값 확인
NOT IN : NULL 있으면 FALSE (NVL 권장)
EX.
select d.dno, d.dname from department d where exists (select e.dno from employee e where d.dno=e.dno);
//10,20,30 만 출력
DNO DNAME
---------- ----------------------------
20 RESEARCH
30 SALES
10 ACCOUNTING
문제 풀이
○ 사원번호 7788인 사원과 담당업무가 같은 사원 표시 (이름, 업무)
select ename, job from employee where job = (select job from employee where eno=7788);
○ 사원번호 7499인 사원보다 급여 많은 사원 (이름, 업무)
select ename, job from employee where salary > (select salary from employee where eno=7499);
ENAME JOB
-------------------- ------------------
JONES MANAGER
BLAKE MANAGER
CLARK MANAGER
SCOTT ANALYST
KING PRESIDENT
FORD ANALYST
○ 최소 급여를 받는 사원의 이름, 업무, 급여 표시
select ename, job, salary from employee where salary = (select min(salary) from employee);
ENAME JOB SALARY
-------------------- ------------------ ----------
SMITH CLERK 800
○ 업무별 평균급여가 가장 작은 담당 업무 찾기 (담당업무, 평균급여)
select job, avg(salary) from employee group by job having avg(salary) = (select round(min(avg(salary)),1) from employee group by job);
JOB AVG(SALARY)
------------------ -----------
CLERK 1037.5
○각 부서의 최소 급여를 받는 사원 이름, 급여, 부서번호
select ename, salary, dno from employee where salary in (select min(salary) from employee group by dno);
ENAME SALARY DNO
-------------------- ---------- ----------
SMITH 800 20
JAMES 950 30
MILLER 1300 10
○ job이 analyst 인 사원보다 급여 적으면서 analyst 아닌 사원들의 사원번호, 이름, 담당업무, 급여 표시
select eno, ename, job, salary from employee where job<>'ANALYST' and salary <all (select salary from employee where job='ANALYST');
ENO ENAME JOB SALARY
---------- -------------------- ------------------ ----------
7566 JONES MANAGER 2975
7698 BLAKE MANAGER 2850
7782 CLARK MANAGER 2450
7499 ALLEN SALESMAN 1600
7844 TURNER SALESMAN 1500
7934 MILLER CLERK 1300
7654 MARTIN SALESMAN 1250
7521 WARD SALESMAN 1250
7876 ADAMS CLERK 1100
7900 JAMES CLERK 950
7369 SMITH CLERK 800
○ MANAGER 없는 사원 이름
select ename from employee where manager is null;
//select ename from employee where eno in (select eno from employee where manger is null);
ENAME
--------------------
KING
○ BLAKE와 동일 부서에 속한 사원 이름, 입사일 표시 (본인제외)
select ename, hiredate from employee where ename<>'BLAKE' and dno in (select dno from employee where ename='BLAKE');
ENAME HIREDATE
-------------------- --------
ALLEN 81/02/20
WARD 81/02/22
MARTIN 81/09/28
TURNER 81/09/08
JAMES 81/12/03
○이름에 K 포함된 사원과 같은 부서에서 일하는 사원 번호, 이름
select eno, ename from employee where dno in (select dno from employee where ename like '%K%') and ename not like '%K%';
ENO ENAME
---------- --------------------
7499 ALLEN
7521 WARD
7654 MARTIN
7844 TURNER
7900 JAMES
7934 MILLER
○부서위치 dallas인 사원 이름, 부서번호, 담당업무
select ename, dno, job from employee where dno=(select dno from department where loc='DALLAS');
ENAME DNO JOB
-------------------- ---------- ------------------
SMITH 20 CLERK
JONES 20 MANAGER
SCOTT 20 ANALYST
ADAMS 20 CLERK
FORD 20 ANALYST
○KING에게 보고하는 사원 이름, 급여
select ename, salary from employee where manager=(select eno from employee where ename='KING');
ENAME SALARY
-------------------- ----------
JONES 2975
BLAKE 2850
CLARK 2450
'Programming > 국비학원' 카테고리의 다른 글
220906 - 오라클 - MERGE문, 뷰 (0) | 2022.09.07 |
---|---|
220905 - 오라클 - 데이터 정의어, 데이터 조작어, 트랜잭션 (0) | 2022.09.06 |
220831 - 오라클 - 숫자, 날짜, 변환, 일반, 그룹 함수, GROUP BY절 (0) | 2022.09.02 |
220830 - 오라클 - SQL PLUS, 쿼리문 (0) | 2022.08.31 |
220829 - 데이터베이스 - SQL PLUS (오라클) - 데이터 질의어 (0) | 2022.08.30 |