-- 테이블 내용 변경하기
update dept01
set loc = (select loc from dept01
where deptno=20)
where deptno=40;
-- 테이블의 내용을 전부 삭제하기
delete emp02;
-- 테이블에 데이터 추가하기
insert into emp02
select * from emp;
drop table emp02 purge;
create table emp02
as
select * from emp;
-- 데이터 삭제하
delete emp02
where deptno = (select dptno
from dept
where dname='영업부');
① = ANY, =SOME은 IN과 의미가 같다.
② 메인 쿼리에서 서브 쿼리의 결과 값으로 하나만 리턴받으려면, 서브 쿼리에서 GROUP BY를 사용해야 한다.
③ ALL은 서브 쿼리에서 돌려주는 모든 값이 비교 조건을 만족할 때, 참이 된다.
④ 메인 쿼리의 SELECT 문에서 select_list에 해당하는 값으로 서브 쿼리를 사용할 수 있는데, 이때 반드시 단일 값만을 리턴해야 한다.
서브 쿼리의 결과 값을 메인 쿼리에서 하나만 리턴받으려면 GROUP BY를 사용할 필요가 없습니다. 일반적으로 서브 쿼리에서 단일 값을 리턴하는지 확인하면 됩니다.
① select ename, sal
② from emp
where sal > (select ③ max(sal), min(sal)
④ from emp);
서브쿼리(subquery)가 여러 개의 값을 반환하는데, 비교 연산자는 하나의 값을 비교해야 한다. 올바른 쿼리를 작성하려면 서브쿼리에서 최대 및 최소 값을 가져와 비교해야 한다.
SELECT ename, sal FROM emp WHERE sal > (SELECT MAX(sal) FROM emp) OR sal > (SELECT MIN(sal) FROM emp);
select ename, sal, deptno
from emp
where deptno ____ (select distinct deptno
from emp
where sal > 500);
① IN
② NOT EXISTS
③ =
④ =SOME
① table_list 문(FROM)
② select_list 문(SELECT)
③ WHERE, HAVING 문
④ GROUP BY 문
update ① table emp
② set sal = sal + 100
where deptno = (select ③ deptno
from dept
④ where dname = '경리부');
① ```sql
select * from emp
where deptno = (select deptno
from dept
where dname = '경리부');
② ```sql
delete emp
where ename = (select ename from emp
where empno = 1001);
③ ```sql
insert into dept01
select * from dept01;
④ ```sql
select * into emp2 from emp;
INSERT INTO emp2 SELECT * FROM emp;
create table emp06
as
select * from emp;
select * from emp06;
SELECT ename, sal, job
FROM emp06
WHERE job != '과장' AND sal > (SELECT MIN(sal) FROM emp06 WHERE job = '과장');
UPDATE emp06
SET sal = sal + 100
WHERE deptno IN (SELECT deptno FROM dept WHERE loc = '인천');
delete from emp06
WHERE deptno IN (SELECT deptno FROM dept WHERE loc = '인천');
select * from emp06;
select * from dept;
SELECT ename, deptno
FROM emp06
WHERE deptno IN (SELECT deptno FROM emp06 WHERE ename = '이문세');
SELECT *
FROM emp06
WHERE job = (SELECT job FROM emp06 WHERE ename = '이문세');
SELECT ename, sal
FROM emp06
WHERE sal >= (SELECT sal FROM emp06 WHERE ename = '이문세');
SELECT ename, deptno
FROM emp06
WHERE deptno in (SELECT deptno FROM dept WHERE loc = '인천');
SELECT ename, sal, mgr
FROM emp06
WHERE mgr in (SELECT empno FROM emp06 WHERE ename = '감우성');
SELECT empno, ename, sal, deptno
FROM emp e
WHERE sal = ( SELECT max(sal)
FROM emp e2
WHERE e.deptno = e2.deptno
GROUP BY deptno );
select deptno, dname, loc
from dept
where deptno in
(select distinct deptno from emp
where job = '과장');
SELECT ename, sal, job
FROM emp06 e
WHERE EXISTS (
SELECT 1
FROM emp06
WHERE job = '과장' AND sal < e.sal
);
-- 필요한 쿼리만 작성해서 저장한 가상 테이블 뷰
create view testview
as
select ename, sal from emp;
select * from testview;
-- emp를 원본 테이블로 하여 emp_copy 테이블 생성하기
create table emp_copy
as
select * from emp;
select * from emp_copy;
-- 30번 부서에 소속된 사원 정보 출력하기
select empno, ename, deptno
from emp_copy
where deptno=30;
-- 30번 부서에 소속된 사원 정보 출력하는 뷰 정의하기
create view emp_view30
as
select empno, ename, deptno
from emp_copy
where deptno=30;
-- 30번 부서에 소속된 사원 정보를 출력하는 뷰 사용하기
select * from emp_view30;
-- user_views 테이블의 구조 살피기
desc USER_VIEWS;
-- 뷰에 insert 문으로 데이터 추가하기
insert into emp_view30
values(1111, 'aaaa', 30);
-- 30번 부서에 소속된 사원 정보를 출력하는 뷰 사용하기
select *
from emp_view30;
-- 기본 테이블을 살피기
select * from emp_copy;
-- 사원 테이블과 부서 테이블을 조인한 뷰 생성하기
create view emp_view_dept as
select e.empno, e.ename, e.sal, e.deptno, d.dname, d.loc
from emp_copy e, dept d
where e.deptno = d.deptno;
-- 사원 테이블과 부서 테이블을 조인한 뷰 사용하기
select * from emp_view_dept;
-- 뷰 삭제하기
drop view emp_view_dept;
-- create view로 뷰를 수정하는 오류를 범한 예
create view emp_view30
as
select empno, ename, sal, comm, deptno
from emp_copy
where deptno=30;
-- emp_view30 뷰의 구조 살피기
desc emp_view30;
-- emp_view30 뷰 변경하기
create OR REPLACE view emp_view30
as
select empno, ename, sal, comm, deptno
from emp_copy
where depno=30;
-- emp_view30 뷰의 구조 살피기
desc emp_view30
-- 테이블이 존재하지 않음을 확인하기
desc employees;
-- 30번 부서에 소속된 사원을 조회하는 뷰 정의하기
create or replace view employees_view
as
select empno, ename, deptno
from employees
where deptno=30;
-- 기본 테이블 없이 뷰 정의하기
create or replace FORCE view employees_view
as
select empno, ename, deptno
from employees
where depno=30;
-- 뷰 내용 살피기
select view_name, text
from user_views;
-- 기본 테이블이 있는 경우에만 뷰가 생성되도록 하기
create or replace NOFORCE view existtable_view
as
select empno, ename, deptno
from employees
shere deptno=30;
-- 뷰 내용 살피기
select view_name, tet
from user_views;
-- force | noforce 옵션 없이 뷰 정의하기
create or replace view existtable_view
as
select empno, ename, deptno
from employees
where deptno=30;
-- 30번 부서에 소속된 사원을 조회하는 뷰 정의하기
create or replace view emp_view30
as
select empno, ename, sal, comm, deptno
from emp_copy
where deptno=30;
-- 30번 부서에 소속된 사원 정보를 출력하는 뷰 사용하기
select *
from emp_view30;
-- 급여가 1200 이상인 사원을 20번 부서로 변경하기
update emp_view30 set deptno=20
where sal>=1200;
-- 30번 부서에 소속된 사원 정보를 출력하는 뷰 사용하기
select *
from emp_view30;
-- 조건 컬럼 값을 변경하지 못하는 뷰 정의하기
create or replace view VIEW_CHK30
as
select empno, ename, sal, comm, deptno
from emp_copy
where deptno=30 WITH CHECK OPTION;
select * from view_chk30;
update view_chk30 set deptno=20
where sal >= 300;
-- emp을 원본 테이블로 하여 emp_copy 테이블 생성하기
create table mp_copy2
as
select * from emp;
-- 조건 컬럼 값을 변경하지 못하는 뷰 정의하기
create or replace view VIEW_CHK30
as
select empno, ename, sal, comm, deptno
from emp_copy2
where deptno=30 WITH CHECK OPTION;
-- 급여가 1200 이상인 사원은 20번 부서로 변경하기
update VIEW_CHK30 set deptno=20
where sal >=1200;
-- 30번 부서에 소속된 사원 정보를 출력하는 뷰 사용하기
select *
from VIEW_CHK30;
WITH READ ONLY 옵션은 뷰를 통해서는 기본 테이블의 어떤 컬럼에 대해서도 내용을 절대 변경할 수 없도록 하는 것이다.
-- 커미션을 모두 1000으로 변경하기
update view_chk30 set comm=1000;
select *
from VIEW
-- ROWNUM 컬럼 값 출력하기
select rownum, empno, ename, hiredate
from emp;
-- 입사일을 기준으로 오름차순 정렬하기
select empno, ename, hiredate
from emp
order by hiredate;
-- 입사일을 기준으로 오름차순 정렬한 후 rownum 컬럼 출력하기
select rownum, empno, ename, hiredate
from emp
order by hiredate;
-- 입사일을 기준으로 오름차순 정렬한 뷰 정의하기
create or replace view view_hire
as
select empno, ename, hiredate
from emp
order by hiredate;
-- 입사일을 기준으로 오름차순 정렬한 뷰로 rownum 컬럼 출력하기
select rownum, empno, ename, hiredate
from view_hire;
-- 입사일이 빠른 사람 5명 가져오기
select rownum, empno, ename, hiredate
from view_hire
where rownum<=5;
-- 인라인 뷰로 입사일이 빠른 사람 5명만 출력하기
select rownum, empno, ename, hiredate
from (select empno, ename, hiredate
from emp
order by hiredate)
where rownum<=5;
-- 인라인 뷰로 원하는 범위 사람 출력하기
select B.*
from (select rownum as rnum, A.*
from (select empno, ename, hiredate
from emp
order by hiredate) A) B
where rnum between 11 and 20;
create table board(
no number(5),
title varchar2(34) not null,
re number(3) default 0,
regdate date default sysdate);
create sequence seq_board
start with 1 increment by 1 nocache;
begin
for i in 1..10002 loop
insert into board
values(seq_board.nextval,
'With A Little Help From My Friends',
trunc(dbms_random.value(0,100)),
sysdate-((10002-i)/24/6));
end loop;
end;
/
set pages 50000;
col regdate for a20;
col title for a34;
col re for 99;
col no for 99999;
select no, title, re,
to_char(regdate,'YYYY-MM-DD hh24:mi:ss') as regdate
from board
where regdate > sysdate - 1/24
order by no desc;
select count(*) from board;
define thisPage=1;
define pageSize=5;
select rownum, no, title, re,
to_char(regdate,'YYYY-MM-DD') as regdate
from board
where rownum between (&thisPage-1)*&pageSize+1 and &thisPage*&pageSize
order by no desc;
define thisPage = 2/
select A.*
from (select no, title, re,
to_char(regdate,'YYYY-MM-DD') as regdate
from board
order by no desc) A
where rownum between (&thisPage-1)*&pageSize+1 and &thisPage*&pageSize;
select B.*
from (select rownum as rnum, A.*
from (select no, title, re, to_char(regdate,'YYYY-MM-DD') as regdate
from board
order by no desc) A) B
where rnum between (&thisPage-1)*&pageSize+1
and &thisPage*&pageSize;
define thisPage=1;
select B.*
from (select rownum as rnum, A.*
from (select no, title, re,
to_char(regdate, 'YYYY-MM-DD') as regdate
from board
order by no desc) A) B
where rnum between (&thisPage-1)*&pageSize+1
and &thisPage*&pageSize;
define thisPage=2/
create table board (
no number,
title varchar2(34) not null,
re number(3) default 0,
regdate date default sysdate);
alter table board add constraint pk_board
primary key(no);
create sequence seq_board
start with 1 increment by 1 nocache;
begin
for i in 1..2000000 loop
insert into board
values(seq_board.nextval,
'With A Little Help From My Friends',
trunc(dbms_random.value(0,100)),
sysdate-((2000000-i)/24/6));
end loop;
end;
/
commit;
set autot on
set timing on
col content noprint
select B.*
from (select rownum as rnum, A.*
from (select no, title, re,
case to_char(regdate,'YYYY-MM-DD')
when to_char(sysdate,'YYYY-MM-DD')
then to_char(regdate,'HH24:MI:SS')
else to_char(regdate,'YYYY-MM-DD')
end as regdate
from board
order by no desc) A) B
where rnum between (&thisPage-1)*&pageSize+1
and &thisPage*&pageSize;
SELECT no, title, re,
case to_char(regdate,'YYYY-MM-DD')
when to_char(sysdate,'YYYY-MM-DD')
then to_char(regdate,'HH24:MI:SS')
else to_char(regdate,'YYYY-MM-DD')
end as regdate
from board
order by no desc
OFFSET 0 ROWS FETCH FIRST 5 ROWS ONLY;