*.LOCK(데이터 읽기 일관성과 락)
-- User1장소에서 접속
update dept
set deptno=70
where dname='부서추가1';

-- User2장소에서 접속
update dept
set deptno=70
where dname='부서추가1';

User1실행후.. User2를 실행하면..
User2에서는 lock현상이 일어남.

User1에서 commit/rollback실행시..
user2에서 실행됨 확인.

질문거리. User2.에서 해소방법 따로없는지?

*.Table 생성
create table table명
(
컬럼명 데이터 타입[(크기)],
...

)

create table dept2
(
deptno number(2),
dname varchar2(14),
loc varchar2(13)
)

*.table 내용 및 구조 복사.
-- dept의 모든 내용과 테이블 구조 복사
create table dept3 as
elect * from dept

drop table dept3;
create table dept3 as
--select * from dept d join emp e using(deptno);
--select * from dept d natural join emp e;
--자동을 사용하면 됨.
--select * from dept d, emp e where d.deptno=e.deptno;
--select * from dept d join emp e on d.deptno=e.deptno;
--안되는 이유 열명중복.

-- dept4만들기.. 원본 dept 부서번호 30이하의 내용만 복사
create table dept4 as
select * from dept where deptno<=30

-- dept5만들기.. 원본 dept 부서번호, 부서명만 복사, 10~50사이만.
create table dept5 as
select deptno, dname from dept where deptno between 10 and 50

-- dept6만들기.. 원본 dept 10,20의 dno, dname
create table dept6 as
select deptno as dno, dname from dept where deptno in (10,20)

-- dept66복사
create table dept66 as
select * from  dept6

-- dept6 데이터 삭제.
delete from dept6;

-- rollback으로 복구
rollback;

-- 데이터 삭제 : truncate table 테이블명;
truncate table dept66;

-- rollback으로 복구
rollback;

select * from dept66;
--선택된 레코드가 없습니다.

-->rollback : 복구 가능한 delete(DML문장) / 안되는 truncate(DML문장아님)

*.table 삭제
drop table table명.
drop table dept5;

-- dept5만들기, dept table 구조만 복사(조건 거짓으로만들어서)
create table dept5
as select * from dept where 10=200;

--dept원본빼고 삭제.
--일일이 삭제함.

*.다중테이블에 다중로우입력.
-- 다중 insert 문법
insert [all | first]
 [when 조건 then]
 into 테이블명 values (컬럼명)
 [when 조건 then]
 into 테이블명 values (컬럼명)
 SubQuery
:all(전체)
:frist(만약 같은 결과값이라면 처음쓰이는곳에서만 표시.다른결과값은 표시)
ex)1조건 MILLER, 2조건 MILLER,FORD라면. 2조건테이블에는 FORD만 들어감.
즉 1조건만족하면 2조건에는 포함되지 않음.

--emp 내용물없는 구조만 복사
--사원번호,사원명,입사일,부서번호있는 empdept테이블 생성

--emp 내용물없는 구조만 복사
--사원번호,사원명,입사일 empdate테이블 생성

create table empdept
as
select empno, ename, hiredate, deptno from emp where 10=20;

create table empdate
as
select empno, ename, hiredate from emp where 10=20;

--emp의 사원번호 7900초과하는
--사원번호,사원명,입사일,부서번호있는 empdept입력.

--emp의 사원번호가 7900초과하는
--사원번호,사원명,입사일 empdate테이블 생성

--다중 1번사용.
insert all
into empdept values (empno, ename, hiredate, deptno)
into empdate values (empno, ename, hiredate)
select ename, empno, hiredate, deptno --순서는 상관없이 컬럼명만상관.
from emp e
where empno>7900;

--연습테이블 데이터 삭제.
delete from empdept;
delete from empdate;

-- 승기사원 입사일 오늘로 수정.
update emp
set hiredate=sysdate
where ename='이승기'

--부서번호 20이하이면 empdept테이블에
--입사일이 82년도이전 이면 empdate테이블에 넣기.
insert all
when deptno<=20 then
into empdept values (empno, ename, hiredate, deptno)
when hiredate <= to_date('1982-12-31','yyyy-mm-dd') then
into empdate values (empno, ename, hiredate)
select ename, empno, hiredate, deptno --순서는 상관없이 컬럼명만상관.
from emp e
where empno>7900;

--부서번호 10이면 empdept테이블에
--입사일이 82년도이전이고 부서번호10인경우는 제외한 empdate테이블에 넣기.
insert first
when deptno=10 then
into empdept values (empno, ename, hiredate, deptno)
when hiredate <= to_date('1982-12-31','yyyy-mm-dd') then
into empdate values (empno, ename, hiredate)
select ename, empno, hiredate, deptno --순서는 상관없이 컬럼명만상관.
from emp e
where empno>7900;

Posted by 말없제이
,

*.SubQuery와 DML의 만남
DML :
insert into 테이블명 () values ()
update 테이블명 set 컬럼='' where 조건.
delete 테이블명 where 조건.

--마케팅부서를 제주도로 이전
update dept
set loc='제주도' where dname='마케팅부'

--60번 부서의 지역을 마케팅부의 지역으로 이전
update dept
set loc=(select loc from dept where dname='마케팅부')
where deptno = 60

--50번 부서의 이름과 지역을 40번부서의 것과 동일하게.
update dept
set loc=(select loc from dept where deptno=40),
dname=(select dname from dept where deptno=40)
where deptno=50
--=>> 복수컬럼이면 동일한 갯수/타입이여야 함
update dept
set (loc,dname)=(select loc,dname from dept where deptno=40)
where deptno=50

--8000,'이승기','사원',50번부서 사원등록
insert into emp
(empno, ename, job, deptno)
values (8000,'이승기','사원',50);

--이승기 사원이 근무하는 부서명은 오락부, 지역은 60번동일
update dept
set (dname,loc) = (select '오락부',loc from dept where deptno=60)
where deptno=(select deptno from emp where ename='이승기');

--이씨가 근무하는 부서 삭제
delete from dept
where deptno = (select deptno from emp where ename like '이%')

*.Transaction
트랜잭션 개념 및 효과 정리해야 :
TCL : commit/rollbakck/savepoint

-- commit 트랜잭션 종료/시작
-- 50, '부서추가1' 추가  -----1
insert into dept
values(50, '부서추가1',null)

-- commit 트랜잭션 종료/시작
-- 60번 부서 지역을 서울 ----2
update dept
set loc='서울'
where deptno=60;
savepoint a1;
-- 50번부서 추가.  -----3
insert into dept
values (70,'부서추가2',null);
savepoint a2;
-- 50번부서지역을 서울로 ------ 4
delete from dept where deptno=50;
savepoint a3;

========
1.DML문법 숙지
insert into 테이블명 () values ()
update 테이블명 set 컬럼='' where 조건.
delete 테이블명 where 조건.

2.트랜잭션 개념정리
 트랜잭션의 일반적인 의미는 정보의 교환이나 데이터베이스 갱신 등
연관되는 작업들에 대한 일련의 연속을 의미하는데,
데이터베이스의 무결성이 보장되는 상태에서
요청된 작업을 완수하기 위한 작업의 기본 단위

 트랜잭션이 성공적으로 끝나기 위해서는
각 작업 단계들이 모두 완성되어야만 하며,
그랬을경우 비로소 이 새로운 내용이
데이터베이스에 실제로 반영된다.
 만약 그렇지 못했을 경우,
즉 어떤 한 작업 단계에서라도 오류가 발생하면
데이터베이스에는 아무런 수정이 이루어지지 않으며,
트랜잭션이 시작되기 이전 상태로 유지된다.

트랜잭션이 성공리에 끝났을때 이루어지는 데이터베이스의 갱신을
"commit" 이라고 부르며,
트랜잭션이 실패되었을때 데이터베이스의 수정 내용이 취소되는 것을
"rollback"이라고 부른다.
트랜잭션의 각 사건들을 관리 감독하는 프로그램을
트랜잭션 모니터라고 하며, 트랜잭션은 SQL에 의해 제공된다.
(ORACLE 에서는 savepoint라고 특정위치 정해줄수 있다.)

Posted by 말없제이
,

SubQuery 연습.

DBTool/Oracle 2009. 7. 7. 09:28

-- martin이 근무하는 부서의 부서명과 지역조회
select dname, loc
from dept
where deptno=
(
select deptno
from emp
where ename='MARTIN'
)

--3000이상의 급여를 받는 사람의 근무하는 부서의 부서번호,사원명,급여조회
select deptno, ename, sal
from emp
where deptno in
(
select distinct(deptno)
from emp
where sal>=3000
)
order by deptno, sal

1.scott의 급여 이상을 받은 사원의 이름,급여,커미션
select ename, sal, comm
from emp
where sal>=
(
select sal from emp where ename='SCOTT'
) and ename<>'SCOTT'

2.clerk업무에 종사하는 사원이 근무하는 부서명?
select dname
from dept
where deptno in
(
select distinct(deptno) from emp where job='CLERK'
)

3.이름에 L을 포함하는 사원과 동일한 부서에 근무하는 사원 모든정보
select *
from emp
where deptno in
(
select distinct(deptno) from emp where ename like '%L%'
)
order by deptno asc, ename asc

4.DALLAS소재부서에 근무하는 사원 모든정보
select *
from emp
where empno in
(
select distinct(empno) from dept where loc='DALLAS'
)

5.SALES부서에 근무하는사원들의 모든정보
select *
from emp
where deptno in
(
select distinct(deptno) from dept where dname='SALES'
)

6.KING에게 보고하느 모든 사원들의 이름과 급여조회
select ename, sal
from emp
where mgr in
(
select distinct(empno) from emp where ename='KING'
)

7.자신의 급여가 전체사원의 평균급여보다 많고,
이름에 S가 들어가는 사원과 동일한 부서에 근무한 사원들의 모든정보
select *
from emp
where empno in
(
select distinct(empno)
from emp
where ename like '%S%'
and sal>=(select avg(sal) from emp)
)

Posted by 말없제이
,

DML(조작어)
insert into 테이블명
[(컬럼)] values (내용)

update 테이블명
set 컬럼=내용
[where 조건]

delete [from] 테이블명 where 조건.
(실제 DB에서삭제는 commit을 통해완료됨.)

-- 개발부이거나 경리부이거나 지역이 미확정된 부서 삭ㄱ제
delete dept where dname in ('개발부','연구원') or loc is null

*.subquery(서브쿼리, 이너쿼리)
mainquery~~ ~(subqurey) ~~ ;
from 안에 들어가는 서버쿼리를 인라인뷰라고 부름.

-단일행부속질의
-복수행부속질의 : in, any, all, exists

--miller가 근무하는 부서의 사원명,부서번호 조회
select ename, deptno
from emp
where deptno in
(
select deptno
from emp
where ename='MILLER'
);

ENAME          DEPTNO
---------- ----------
CLARK              10
KING               10
MILLER             10

--7782 사원이 받는 급여이상을 받는 사원번호,사원명,급여,커미션 조회
 1  select empno, ename, sal, comm
 2  from emp
 3  where sal >= (
 4  select sal
 5  from emp
 6  where empno=7782
 7* )
 8  /

    EMPNO ENAME             SAL       COMM
--------- ---------- ---------- ----------
     7566 JONES            2975
     7698 BLAKE            2850
     7782 CLARK            2450
     7788 SCOTT            3000
     7839 KING             5000
     7902 FORD             3000

-- MANAGER일을 하는 사원들의 평균급여보다 많이받는 모든정보조회

  1  select *
  2  from emp
  3  where sal>=
  4  (
  5  select avg(sal)
  6  from emp
  7  group by job
  8  having job='MANAGER'
  9* )
SQL> /

     EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM     DEPTNO
---------- ---------- --------- ---------- -------- ---------- ---------- ----------
      7566 JONES      MANAGER         7839 81/04/02       2975                    20
      7698 BLAKE      MANAGER         7839 81/05/01       2850                    30
      7788 SCOTT      ANALYST         7566 82/12/09       3000                    20
      7839 KING       PRESIDENT            81/11/17       5000                    10
      7902 FORD       ANALYST         7566 81/12/03       3000                    20

*.서브쿼리 연산자
- in : 나열된 조건과 같은것.
- all : 조건의 모든결과일치
- any/some : 조건 하나이상 조건 만족.
- exists : 하나라도 값이 있는지.

-- MANAGER일을 하는 사원들의 급여보다 많이받는 모든정보조회
 select *
 from emp
 where sal>any
 (
 select sal
 from emp
 where job='MANAGER'
 )
 /

 EMPNO ENAME      JOB              MGR HIREDATE        SAL       COMM     DEPTNO
------ ---------- --------- ---------- -------- ---------- ---------- ----------
  7566 JONES      MANAGER         7839 81/04/02       2975                    20
  7698 BLAKE      MANAGER         7839 81/05/01       2850                    30
  7788 SCOTT      ANALYST         7566 82/12/09       3000                    20
  7839 KING       PRESIDENT            81/11/17       5000                    10
  7902 FORD       ANALYST         7566 81/12/03       3000                    20


-- 7698사원 밑에서 일하는 사원번호,사원명,부서번호,부서명 조회

  select e.empno, e.ename, e.deptno, d.dname
  from emp e join dept d on e.deptno=d.deptno and e.mgr=7698
> /

  EMPNO ENAME          DEPTNO DNAME
------- ---------- ---------- --------------
   7499 ALLEN              30 SALES
   7521 WARD               30 SALES
   7654 MARTIN             30 SALES
   7844 TURNER             30 SALES
   7900 JAMES              30 SALES

select e.empno, e.ename, e.deptno, d.dname
from emp e, dept d
where e.empno in
(
select empno
from emp
where mgr=7698
)
and e.deptno=d.deptno

--------------
research 부서의 근무하는 모든 사원정보 조회
select e.*
from emp e join dept d on e.deptno=d.deptno and d.dname='RESEARCH'

select e.*
from emp e
where deptno in
(
select deptno
from dept d
where d.dname='RESEARCH'
)/

Posted by 말없제이
,

-DML : 조작어(insert, delete, update)
-DDL :
*.객체생성
create 객체타입 객체명( ... )

*.객체수정
alter 객체타입 객체명
 -추가/변경/삭제
-사용시 주의점 : 컬럼데이터 타입, 컬럼크기, 제약조건 확인해서 수정해아함.

alter user user명
[idenfified by 비밀번호]
[account lock]

*.객체삭제
drop 객체타입 객체명( ... )

*.데이터 입력
insert into 테이블명 [(컬럼명[,..])] values (컬럼명[,..])
- '~' : 문자
- 컬럼타입,컬럼크기[,제약조건(not null,unique,pk,fk,ck)]도 확인
- null : 묵시적/명시적(null,'')

insert into dept (deptno, dname, loc)
values (50,'It부','서울')

insert into emp (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values(8000,'원빈','홍보모델',7934,'2009/07/01',3500,350,30)

insert into emp
values(8100,'송해교','인사부',7902,'2009/01/01',3500,300,20)

70,신속정확한경리부,광주
insert into dept values (70,'정확한경리부','광주')

*.데이터 삭제
delete [from] 테이블명 [where 조건]

*.데이터 수정
update 테이블명
set 컬렴명=새값
[where 조건]

--50번 부서의 부서명은 개발부, 인천으로 이전

*.변수명/치환변수(&,&&사용)
&변수명 = 변수값.
&&변수명 = 변수값 : 기존사용하던 변수인경우 묻지않고 치환됨.

emp table에
8200,이승기,개발자
8300,김동률, 연구원
8400,임의명,임의업무
8500,임의명,임의업무

insert into emp (empno, ename, job)
values (&no, '&na', '&job')

Posted by 말없제이
,

self join/outer join

DBTool/Oracle 2009. 6. 30. 13:41

*.join
*-self join : 자기자신의 테이블에서 특정값호출위해 조인.

-- 사원번호, 사원명, 상사의 사원번호, 상사이름
ex)
select a.empno as "사원번호", a.ename as "사원명", b.mgr as "상사사번", b.ename as "상사이름"
from emp a, emp b
where a.empno = b.mgr


-- 사원명, 부서번호, 부서이름 조회
select e.ename, e.deptno, d.dname
from emp e join dept d on e.deptno=d.deptno

40번 부서 사람이 없으니, 조회 안됨.

*-outer join : (+) 연산자로 추가해서 반대쪽에 있는 데이터 null값도 보여줌(반대편 컬럼전체보여줌).
ex)
select e.ename, e.deptno, d.dname
from emp e, dept d
where e.deptno(+)=d.deptno
ex)
select e.ename, e.deptno, d.dname
from emp e full outer join dept d
on e.deptno=d.deptno(+)
ex)
select e.ename, e.deptno, d.dname
from emp e left outer join dept d
on e.deptno=d.deptno(+)
ex)
select e.ename, e.deptno, d.dname
from emp e right outer join dept d
on e.deptno(+)=d.deptno

--
--1.EQUI
--EMPNO, ENAME, DNAME, LOC
select e.empno, e.ename, d.dname, d.loc
from emp e, dept d
where e.deptno = d.deptno;

--2.NATURAL
--EMPNO, ENAME, DNAME
select e.empno, e.ename, d.dname
from emp e natural join dept d;

--3.JON USING
--EMPNO, ENAME, DNAME, LOC
select e.empno, e.ename, d.dname, d.loc
from emp e join dept d using(deptno);

--4.JOIN ON
--EMPNO, JOB, SAL, DNAME, LOC
select e.empno, e.job, e.sal, d.dname, d.loc
from emp e join dept d on e.deptno=d.deptno;

--1.사원들의 이름, 부서번호, 부서이름
select e.ename, d.deptno, d.dname
from emp e join dept d on e.deptno=d.deptno;

--2.부서번호가 30인 사람들의 이름, 직급, 부서번호, 부서위치
select e.ename, e.job, e.deptno, d.loc
from emp e join dept d on e.deptno=d.deptno
where e.deptno=30;

--3.커미션 받는 사람이름, 커미션, 부서이름, 부서위치
select e.ename, e.comm, d.deptno, d.loc
from emp e join dept d on e.deptno=d.deptno
where comm is not null;

--4.DALLAS에서 근무하는 사원 이름, 직급, 부서번호, 부서이름
select e.ename, e.job, e.deptno, d.dname
from emp e join dept d on e.deptno=d.deptno
where d.loc='DALLAS';

--5.이름에 A가 들어가는 사원들의 이름과 부서이름
select e.ename, d.dname
from emp e join dept d on e.deptno=d.deptno
where e.ename like '%A%';

--6.사원이름과 직급, 급여, 급여등급
select e.ename, e.job, e.sal, s.grade
from emp e join salgrade s on e.sal between s.losal and s.hisal;

--7.사원이름, 부서번호, 해당사원과 같은부서에 근무하는 사원을 출력(self join)
select e.ename as "나의 이름", e.deptno, e1.ename as "그대의 이름"
from emp e join emp e1 on e.deptno=e1.deptno and e.ename<>e1.ename
order by e.ename asc;

Posted by 말없제이
,

*.Join
- join의 개념
- join의 종류
*.카르테시안 product 기법(기본)
Cross조인(모든 정보를 보여줌)
ex)
select * from emp, dept;
ex)
select * from emp cross join dept;
ex)
SQL> select ename, deptno, dname
  2  from emp,dept
  3  ;
select ename, deptno, dname
              *
1행에 오류:
ORA-00918: 열의 정의가 애매합니다
-- 어느테이블 소유인것인지 명확하게 해주면 해결
-- "."(dot)을 이용해서 사용.
table명.컬럼명

SQL>
select emp.ename, emp.deptno, dept.dname
from emp,dept

- 테이블명 단축도 가능(alias사용가능-테이블은 공백만사용)
select a.ename, a.deptno, b.dname
from emp a, dept b


*.EQUI Join 기법 : 동일한 값으로 조인하는방법
1.각 테이블의 동일한값을 where에 =로 명시 [where 에 동일값 표시]
ex)
select emp.ename, emp.deptno, dept.dname
from emp,dept
where emp.deptno = dept.deptno

2.join ~ on : from절에 테이블명 join ~ on 비교될 컬럼명.
ex)
select e.ename, e.deptno, d.dname
from emp e join dept d on e.deptno = d.deptno

3.join ~ using(~) : from절에 테이블명 join ~ using(컬럼명) 사용가능
ex)
select e.ename, deptno, d.dname
from emp e join dept d using(deptno)

4.natural join : Oracle에 알아서 명시해라.
select e.ename, deptno, d.dname
from emp e natural join dept d


*.Non-EQUI Join 기법 : 특정범위값으로 조인하는 방법
 -- 사원명, 급여, 급여등급(등급당 최저급여, 등급당 최급여) 조회
select a.ename, a.sal, b.grade, b.losal, b.hisal
from emp a, salgrade b
where a.sal between b.losal and b.hisal


Posted by 말없제이
,

*.날짜함수

  1  select sysdate, sysdate-1, sysdate+1, to_char(sysdate+(1/2),'yy-mm-dd hh24:mi')
  2* from dual
  3  /

SYSDATE  SYSDATE- SYSDATE+ TO_CHAR(SYSDAT
-------- -------- -------- --------------
09/06/26 09/06/25 09/06/27 09-06-26 21:37

*.months_between : 날짜와 날짜사이의 개월을 계산

  1  select sysdate,months_between(sysdate,to_date('2009-01-01'))
  2  from emp
  3* where empno=7788
SQL> /

SYSDATE  MONTHS_BETWEEN(SYSDATE,TO_DATE('2009-01-01'))
-------- ---------------------------------------------
09/06/26                                    5.82029757

*.add_months : 날짜에 개월을 더한 날짜 계산.

  1  select sysdate,add_months(sysdate,2)
  2  from emp
  3* where empno=7788
SQL> /

SYSDATE  ADD_MONT
-------- --------
09/06/26 09/08/26

*.last_day : 해당월의 마지막일
*.next_day : 다가오는 요일의 날짜를 반환.


  1  select sysdate, last_day(sysdate), next_day(sysdate,'토')
  2  from emp
  3* where empno=7788
SQL> /

SYSDATE  LAST_DAY NEXT_DAY
-------- -------- --------
09/06/26 09/06/30 09/06/27

*.round/trunc : 적용될 날짜형태받아서 하위에서 반올림/절삭

  1  select sysdate, round(sysdate,'mm'), trunc(sysdate,'dd')
  2  from emp
  3* where empno=7788
SQL> /

SYSDATE  ROUND(SY TRUNC(SY
-------- -------- --------
09/06/26 09/07/01 09/06/26

  1  select sysdate, to_char(round(sysdate,'hh'),'yy/mm/dd HH24:mi:ss'), trunc(sysdate,'hh')
  2  from emp
  3* where empno=7788
SQL>
SQL> /

SYSDATE  TO_CHAR(ROUND(SYS TRUNC(SY
-------- ----------------- --------
09/06/26 09/06/26 11:00:00 09/06/26


  1  select sysdate, to_char(sysdate,'ddd'), to_char(sysdate,'dd'), to_char(sysdate,'d')
  2  from emp
  3* where empno=7788
SQL> /

SYSDATE  TO_ TO T
-------- --- -- -
09/06/26 177 26 6


*.Null관련 함수
- nvl(exp1, exp2) : 첫인수가 null이면 두번째인수로 대체
- nvl2(exp1, exp2, exp3) : 첫인수가 null가 아니면 두번째 인수대체, null이면 세번째 인수대체

  1  select comm, nvl(comm, 90), nvl2(comm,999,90)
  2  from emp
  3* where sal >= 1500
SQL> /

      COMM NVL(COMM,90) NVL2(COMM,999,90)
---------- ------------ -----------------
       300          300               999
                     90                90
                     90                90
                     90                90
                     90                90
                     90                90
         0            0               999
                     90                90

- nullif : 함수 두개의 표현식을 비교해 동일하면 null, 일치하지않으면 첫번째값 반환.
nullif(exp1, exp2)

SQL> select comm, nullif(comm, 0)
  2  from emp
  3  where comm is not null
  4  ;

      COMM NULLIF(COMM,0)
---------- --------------
       300            300
       500            500
      1400           1400
         0

- coalesce : 인수중의 null아닌 첫번째 인수 반환. 없으면 null.
  1  select comm, coalesce(comm, 77)
  2* from emp
SQL> /

      COMM COALESCE(COMM,77)
---------- -----------------
                          77
       300               300
       500               500
                          77

*.decode 함수 : if~case 알고리즘 간단한표현, 연산자는 '='만 가능. 불만족시 null반환.
decode(표현식|컬럼명, 찾는값1, 리턴값1, 찾는값2,리턴값2, [default값])

  1  select ename, sal, decode(ename, 'ALLEN', sal)
  2* from emp
SQL> /

ENAME             SAL DECODE(ENAME,'ALLEN',SAL)
---------- ---------- -------------------------
SMITH             800
ALLEN            1600                      1600
WARD             1250
JONES            2975
MARTIN           1250
BLAKE            2850
CLARK            2450
SCOTT            3000
KING             5000
TURNER           1500
ADAMS            1100


SQL> -- 10번 부서 급여 100 추가
SQL> -- 20번 부서 급여 200추가
SQL> -- 그외 9000 일괄 지급
  1  select ename, deptno, decode
  2  (
  3   deptno, 10, sal+100,
  4   20, sal+200,
  5   9000
  6  )
  7* from emp
SQL> /

ENAME          DEPTNO DECODE(DEPTNO,10,SAL+100,20,SAL+200,9000)
---------- ---------- -----------------------------------------
SMITH              20                                      1000
ALLEN              30                                      9000
WARD               30                                      9000
JONES              20                                      3175
MARTIN             30                                      9000
BLAKE              30                                      9000
CLARK              10                                      2550
SCOTT              20                                      3200
KING               10                                      5100
TURNER             30                                      9000
ADAMS              20                                      1300

*.case 함수
decode함수기능 확장, 산술연산, 관계연산, 논리연산 비교가능.
case [표현식] when 조건 then 조건만속시 실행코드
else 이후 불만족시 코드.
end


SQL> --급여가 1300이하이면 '급여올려주삼'
SQL> --1300초과하면서 2999이하이면 '나도 올려줘'
SQL> --2999초과 4000이하 '희망~!'
SQL> --그 외 '나두~~'

  1  select ename, sal,
  2  case when sal<1300 then '급여올려주삼'
  3   when sal>=1300 and sal<=2999 then '나도 올려줘'
  4   when sal<4000 then '희망!'
  5  else '나두~~'
  6  end
  7* from emp
SQL> /

ENAME             SAL CASEWHENSAL<
---------- ---------- ------------
SMITH             800 급여올려주삼
ALLEN            1600 나도 올려줘
WARD             1250 급여올려주삼
JONES            2975 나도 올려줘
MARTIN           1250 급여올려주삼
BLAKE            2850 나도 올려줘
CLARK            2450 나도 올려줘
SCOTT            3000 희망!
KING             5000 나두~~



===============
1. 사원명, 급여 "한달급여", "일당" 구하기 / 한달 20일근무
 select ename, sal, sal/20
 from emp

2. 사원명,입사일,입사한 달의 근무일수 출력(날마다 근무)
select ename, hiredate, last_day(hiredate)-hiredate
from emp

3. 우리 과정 개강한지 오늘로 몇일?
select sysdate-to_date('2009-05-25','yyyy-mm-dd')
from dual


Posted by 말없제이
,

*.함수
- 집계함수
- 문자/숫자/날짜 함수
- 형변환함수(to_char/number/date)

- 명시적 함수
- 묵시적 함수
---
*.문자함수
instr('대상문자열',찾는문자,시작위치,몇번째것을 찾을건지);
substr('대상문자열',시작위치,length);

*.숫자함수
- round : 반올림 : round(123.17,1) -> 123.2
소수점 반올림수 : 순간해놓으면 나중에 아차하는.
3__6__2_._7_1_2;
-3_-2_-1__0 1 2
- trunc : 절삭 : trunc(123.17, 1) -> 123.1
select round(362.712,-2), round(362.712,0), round(362.712), round(362.712,1)
from dual

ROUND(362.712,-2) ROUND(362.712,0) ROUND(362.712) ROUND(362.712,1)
----------------- ---------------- -------------- ----------------
              400              363            363            362.7

- mod : 나머지값 : mod(12,10) -> 2
- ceil : 지정한 값보다 큰수중 가장작은정수 : ceil(123.17) -> 124
- floor : 지정한 값보다 작은수중 가장큰정수 : floor(123.17) -> 123
select ceil(123.17), floor(123.17), ceil(-123.17), floor(-123.17), mod(12,10)
from dual

CEIL(123.17) FLOOR(123.17) CEIL(-123.17) FLOOR(-123.17) MOD(12,10)
------------ ------------- ------------- -------------- ----------
         124           123          -123           -124          2

- sign : 기호를 반환. 양수이면 1, 0이면 0, 음수이면 -1..

SQL> select sign(10), sign(0), sign(-10)
  2  from dual;

  SIGN(10)    SIGN(0)  SIGN(-10)
---------- ---------- ----------
         1          0         -1

*.데이터 타입의 변환
to_char(날짜, 날짜시간format')
to_char(숫자, 'formaht

select ename, sal, to_char(round(sal/13, 1),'999.9') as monthSal
from emp
order by sal asc
ENAME             SAL MONTHS
---------- ---------- ------
SMITH             800   61.5
....
MARTIN           1250   96.2
MILLER           1300  100.0

to_date(' ', '날짜시간format') : 문자를 date형으로 변환.


=========================
1.자신의 생년월일을  년도4자리-월영문축약-일두자리 출력
select to_char(to_date('2079329','yyyymmdd'), 'yyyy-mon-dd') from dual
2.November27을 11월 27일로 출력
select to_char(to_date('November27','monthdd'), 'yy"월" dd"일"') from dual


select to_number('10') from dual


-- 20번 부서사원명, 부서번호 조회
select ename, deptno
from emp
where deptno=to_number('20')

Posted by 말없제이
,

*.함수
함수명(~)

SQL> -- 업무별 최고급여,최저급여,총급여,평균급여, 인원수 조회
SQL> select job, max(sal), min(sal), sum(sal), avg(sal), count(*)
  1  from emp
  2  group by job
  3  ;
SQL> /

JOB         MAX(SAL)   MIN(SAL)   SUM(SAL)   AVG(SAL)   COUNT(*)
--------- ---------- ---------- ---------- ---------- ----------
ANALYST         3000       3000       6000       3000          2
CLERK           1300        800       4150     1037.5          4
MANAGER         2975       2450       8275 2758.33333          3
PRESIDENT       5000       5000       5000       5000          1
SALESMAN        1600       1250       5600       1400          4

*.group by ~ havaing ~ ... : 그룹별로 구분
select ~
from ~
[where 조건]
[group by 기준]
[having 그룹조건]
[order by 정렬]

SQL> --급여가 3000이상되는 사원에 한해
SQL> --업무별 최고급여가 2000 초과하는...
SQL> edit
1  select job, max(sal), min(sal), sum(sal), avg(sal), count(*)
2  from emp
3  group by job
4* having max(sal)>2000
L> /

B         MAX(SAL)   MIN(SAL)   SUM(SAL)   AVG(SAL)   COUNT(*)
------- ---------- ---------- ---------- ---------- ----------
ALYST         3000       3000       6000       3000          2
NAGER         2975       2450       8275 2758.33333          3
ESIDENT       5000       5000       5000       5000          1

ex)
select deptno, max(sal), min(sal), (max(sal)-min(sal)) as cap
from emp
--where deptno in (20,30)
group by deptno
having min(sal)>2500 and deptno in (20,30)
/

*.문자함수
trim( ) : 공백 제거
Rtrim('~','A') : 오른쪽으로 잘라버림
Ltrim('~','A') : 왼쪽으로 잘라버림
ex)

  1  select rtrim('과학수사과','과'), ltrim('과학수사과','과'), trim('    ab     ')
  2* from dual
  3  ;

RTRIM('  LTRIM('  TR
-------- -------- --
과학수사 학수사과 ab


Rpad('~',20,'#') : ~부분 오른쪽을 ~포함 20자리로 만들고 부족한 부분은 '#'으로 채워넣음.
Lpad('~',20,'#') : ~부분 왼쪽을 ~포함 20자리로 만들고 부족한 부분은 '#'으로 채워넣음.
ex)

L> select rpad('www',10,'*'), lpad('www',10,'*')
2  from dual
3  ;

AD('WWW' LPAD('WWW'
-------- ----------
w******* *******www

length() : 문자열 길이 구하는 함수
lengthb() : 문자열을 비트로 구하는 함수
  1  select length('oracle'), length('오라클')
  2* from dual
  3  ;

LENGTH('ORACLE') LENGTH('오라클')
---------------- ----------------
               6                3

SQL>

instr(문자열, '특정문자', 시작위치, 번째) -> position
 
SQL> select instr('ORCLE','LE')
  2  from dual
  3  ;

INSTR('ORCLE','LE')
-------------------
                  4

--사원이름에 L이 포함되는 사원에 한해.
--사원이름에 L이 몇번째 위하는 지 출력.

  1  select ename, instr(ename, 'L')
  2  from emp
  3* where instr(ename, 'L') > 0
SQL> ;
SQL> /

ENAME      INSTR(ENAME,'L')
---------- ----------------
ALLEN                     2
BLAKE                     2
CLARK                     2
MILLER                    3


str(문자열, 시작위치, length) -> 문자열 형태로 리턴.
 
  1  select substr('oh~happy!day', 4,3), substr('oh~happy!day', -4,3)
  2* from dual
  3 
SQL> /

SUB SUB
--- ---
hap !da

-. 80년 11월 23일 표시
  1  select substr('801123-1234567',1,2)||'년 '
  2  ||substr('801123-1234567',3,2)||'월 '
  3  ||substr('801123-1234567',5,2)||'일'
  4* from dual
SQL> /

SUBSTR('801123
--------------
80년 11월 23일


전화번호 02)112-3444 중간번호 추출
select substr
(
'031)2222-1111',instr('031)2222-1111',')')+1,
 (
 instr('031)2222-1111','-') - (instr('031)2222-1111',')')+1)
 )
) as '지역번호'
from dual

Posted by 말없제이
,