##개요
데이터베이스는 모든 프로그램의 핵심이며 데이터를 효율적으로 관리하는 방법으로 DBMS(DataBase Management System) 라는 소프트웨어를 사용하게 된다.
데이터베이스를 사용하는 목적은 다음과 같다.
- 데이터 중복의 최소화
- 데이터의 공유
- 데이터의 보안유지
- 데이터의 무결성 유지
- 데이터의 독립성
다양한 DBMS 중에서 가장 잘 알려진 것이 관계형 데이터베이스 시스템(RDBMS) 이다. RDBMS로는 Oracle, MS-SQL, MySQL 등이 있다. RDBMS는 정형화된 데이터 항목들의 집합체로서 확장이 쉽다는 장점이 있다. 처음 데이터베이스를 만든 후 관련되는 응용 프로그램들을 변경하지 않고도 새로운 데이터 항목을 데이터베이스에 추가할 수 있다. RDBMS는 2차원 테이블 구조로 데이터를 관리하는데, 열을 칼럼(column)이라고 하며 행을 레코드(record)라고 한다. 데이터의 중복을 피하면서 무결성을 보장하기 위해서 다양한 제약 조건을 지정할 수 있다.
##사용자 계정 관련
커맨드 창에서
sqlplus 아이디/비밀번호 혹은 sqlplus 아이디 입력 후 비밀번호 입력하여 로그인
이 후 모든 예제는 오라클 설치시 기본적으로 생성되는 scott 아이디로 실습한다. 이 아이디에는 실습을 위한 테이블들이 자동적으로 생성되어 있다.
conn 사용자/비밀번호
- connection의 약자로 sql에 접속된 상태에서 다른 사용자로 로그인
show user;
- 접속한 user 정보를 출력
alter user 사용자 identified by 비밀번호
- 사용자 비밀번호를 변경
alter user 사용자 account unlock
- 사용자의 lock을 해제
alter user 사용자 identified by 비밀번호 account unlock
- 사용자 비밀번호를 변경 후 계정의 lock을 해제
##select 문
select * from tab;
- 접속된 계정이 소유한 테이블 목록을 출력
desc 테이블
- 테이블 구조를 출력한다.
select * from 테이블
- 테이블의 모든 데이터 출력
select 칼럼, 칼럼 from 테이블
- 테이블의 특정 칼럼의 데이터 출력
select deptno as “부서번호” from emp
- depno를 별칭으로 출력 가능하며 이때 as는 생략이 가능하다.
select distinct job from emp
- distinct 키워드로 중복을 제거한 job의 정보 출력
select empno, ename, sal from emp where sal>=3000
- 급여가 3000 이상인 사원 정보 출력
select * from emp where ename=’SCOTT’
- 이름이 scott인 사원의 정보 출력, sql문은 대소문자를 구분 안하지만 데이터는 대소문자를 구분하므로 주의해야한다.
select * from emp where deptno <> 10
- 부서 번호가 10이 아닌 사원
select * from emp where sal >= 1000 and sal <= 3000 혹은 select * from emp where sal between 1000 and 3000
- 급여가 1000~3000사이인 사원
select * from emp where sal in (1300, 1500, 1600)
- 급여가 1300 또는 1500 또는 1600인 사원 정보
select * from emp where ename like ‘K%’
- 이름이 ‘K’로 시작하는 사원
select * from emp where ename like ‘_A%’
- 2번째에 ‘A’가 들어가는 사원
select * from emp where comm is not null
- 커미션을 받는 사람
select * from emp order by empno asc
- 사번의 오름차순 정렬, 오름차순은 기본이기 때문에 asc 생략이 가능하다.
select * from emp where order by empno desc
- 사번의 내림차순 정렬
select ename, sal, sal*12 “연봉” from emp
- 사원의 연봉 계산
select ename, sal, comm, nvl(comm, 0), sal*12+nvl(comm,0) “연봉” from emp
- 커미션을 포함한 연봉 계산, comm에 null이 있는 경우 0으로 대체해서 계산해준다.
##Group 함수
합계: sum()
select sum(sal) from emp
카운트: count()
select count(*) from emp
평균: avg()
select avg(sal) from emp
최대, 최소: max()
, min()
###Group by
직업별 급여 평균 select job, avg(sal) from emp group by job
###Having
직업별 급여 평균(단, 평균 2000이상) select job, avg(sal) from emp group by job having avg(sal) >= 2000
##내장 함수
샘플 테이블 dual
- select 1234*12 from dual
round()
: 반올림
- select deptno, round(sal, -3) from emp where deptno=30;
lower()
: 모든 문자를 소문자로 변환
upper()
: 모든 문자를 대문자로 변환
initcap()
: 첫자만 대문자로 변환
concat()
: 문자열 연결
- select concat(‘a’, ‘bc’) from dual;
length()
, lengthb()
: 문자열 길이
substr()
, substrb()
: 문자열 추출
instr()
: 문자열 시작 위치
lpad()
, rpad()
: 자리 채우기
trim()
: 컬럼이나 대상 문자열에서 특정 문자가 첫번째 글자이거나 마지막 글자이면 잘라내고 남은 문자열만 반환
abs()
: 절대값
floor()
: 소수점 이하 버리기
trunc()
: 특정 자리 자르기
mod()
: 나머지 연산
sysdate()
: 현재 날짜
months_between()
: 개월 수 구하기
add_months()
: 개월 수 더하기
- select add_months(sysdate, 4) from dual;
next_day()
: 다가올 요일에 해당하는 날짜
- select next_day(sysdate, ‘일요일’) from dual;
last_day()
: 해당 달의 마지막 일 수
- select last_dat(sysdate) from dual;
to_char()
: 문자열로 반환
- select to_char(sysdate, ‘yyyy-mm-dd’) from dual;
to_date()
: 날짜형으로 변환
- select to_date(‘2015/3/2’, ‘yyyy/mm/dd’) from dual;
nvl()
: NULL인 데이터를 다른 데이터로 변경
- select ename, nvl(comm, 0) from emp;
decode()
: switch 문과 같은 기능
case()
: if elseif else
##테이블 생성/수정/삭제
테이블 생성: create
create table exam01
(
num number(2),
name varchar2(20),
sal number(7, 2)
);
기존 테이블과 동일하게 테이블 만들기
- create table exam02 as select * from emp;
기존 테이블에서 새로운 컬럼 추가 alter add
- alter table exam01 add (job varchar2(10));
테이블 구조 수정: 필드 수정 alter modify
- alter table exam01 modify (job varchar2(20));
테이블 구조 수정: 필드 삭제 alter drop column
- alter table exam01 drop column job;
테이블 삭제 drop
- drop table exam02
임시 테이블 삭제
- purge recyclebin;
처음부터 테이블 완전 삭제
- drop table exam02 purge;
테이블 이름 변경 rename
- rename exam01 to exam02;
테이블 내의 모든 데이터(레코드) 삭제 truncate
- truncate table exam01;
##오라클 자료형
- 정수형 타입 : number(2)는 총 자리수가 2자리인 정수형 값이 필드에 저장된다.
- 실수형 타입 : number(6, 2)는 소수점을 포함한 총 자리수가 6자리이고, 2는 소수점 둘째자리까지 있는 실수형 값이 저장된다.
- 가변형 문자열 : varchar2 - 입력 데이터가 실제 크기를 넘어서면, 넘어선 크기만큼 자료형 크기가 늘어나지 않으며 그 이하면 그 크기만큼 줄어들어 저장된다.
- 고정형 문자열 : char - char(10)에서 5크기 만큼 삽입해도 10만큼 저장된다.
##테이블명, 컬럼명 명명 규칙
- 반드시 문자로 시작해야됨.
- 1~30자까지 가능.
- A~Z까지의 대소문자와 0~9까지의 숫자 조합, 특수기호는 (_ $ #)만 가능.
- 오라클에서 사용되는 예약어나 다른 객체명과 중복 불가.
- 공백 허용 안됨.
##데이터 삽입/수정/삭제
데이터 입력 : insert into
- insert into exam02(deptno, dname, loc) values (10, ‘account’, ‘korea’);
데이터 입력 : 행 생략(테이블에 저장된 데이터 순서대로 넣어야한다.)
- insert into exam02 values(20, ‘account’, ‘korea’);
null 값 입력
- insert into exam02 values(30, ‘research’, null);
부서 번호 변경 : 필드의 데이터 변경 update set
- update exam03 set deptno=30
급여 10% 인상
- update exam03 set sal=sal*1.1;
부서번호가 10인 사원의 부서번호를 20으로 변경
- update exam03 set deptno=20 where deptno=10;
사원 이름이 SCOTT인 자료의 부서번호를 10, 직급을 MANAGER로 변경
- update exam03 set deptno=10, job=’MANAGER’ where ename=’SCOTT’;
30번 부서 사원을 삭제 delete
- delete from exam03 where deptno=30
모든 자료 삭제
- delete from exam03;
##join
두 개 이상의 테이블에 나뉘어져 있는 데이터를 한 번의 sql문으로 원하는 결과를 얻을 수 있는 기능 Join 자세히
Cross Join
2개 이상의 테이블이 조인될 때 where절에 의해 공통되는 컬럼에 의한 결함이 발생되지 않는 경우를 의미한다. 아무런 의미 없는 Join이다.
select * from emp, dept;
Equi Join
가장 많이 사용되는 방법으로 조인대상이 되는 두 테이블에서 공통적으로 존재하는 컬럼을 연결하여 결과를 생성 하는 조인 방법
select * from emp,dept where emp.deptno=dept.deptno
select ename, dname from emp e, dept d where e.deptno=d.deptno and ename='SCOTT'
Non-Equi Join
값을 비교하면서 두 개의 테이블을 연결하는 조인방법
select ename,sal,grade from emp,salgrade where sal between losal and hisal;
Self Join
하나의 테이블 내에서 조인을 해야 원하는 자료를 얻는 join 방법
select employee.ename, manager.ename
from emp employee, emp manager
where employee.mgr = manager.empno;
Outer Join
select employee.ename, manager.ename
from emp employee, emp manager
where employee.mgr = manager.empno(+)
ANSI Join
여러 DBMS 간의 공통된 sql 명령어 규악
Cross join
select * from emp cross join dept;
Inner join(Equi join)
select ename, dname from emp inner join dept on emp.deptno = dept.deptno where ename=’SCOTT’
select emp.ename, dept.dname from emp inner join dept using (deptno);
select ename, dname from emp natural join dept;
Outer join
서브쿼리
- 서브쿼리는 하나의 select 문장의 절 안에 포함된 또 하나의 select 문이다.
- 메인쿼리/서브쿼리
- 서브쿼리는 비교 연산자의 오른쪽에 기술해야하고 반드시 괄호로 둘러쌓아야야한다.
- 서브쿼리는 메인 쿼리가 실행되기 이전에 한 번만 실행이된다.
- 단일행 서브쿼리, 다중행 서브쿼리
[문제] SCOTT와 동일한 직급(job)을 가진 사원을 출력하는 sql문을 작성해 보세요.
SQL>select ename, job
from emp
where job = ( select job
from emp
where ename = 'SCOTT'
);
[문제] SCOTT의 급여와 동일하거나 더 많이 받는 사원명과 급여를 출력해보세요.
SQL>select ename, sal
from emp
where sal >= ( select sal
from emp
where ename = 'SCOTT'
);
###서브쿼리 & 그룹 함수
[문제] 평균 급여보다 더 많은 급여를 받는 사원 출력하세요.
SQL>select ename, sal
from emp
where sal > ( select avg(sal)
from emp
);
###다중행 서브쿼리
- IN연산자 - 서브쿼리의 출력결과중 하나라도 일치하면 참이 된다.
- ALL 연산자
- 서브쿼리의 출력결과와 모두 일치하면 참이된다.
-
all은 ‘모든 비교값보다 크냐’고 묻는 것이 되므로 최대값보다 더 크면 참이 된다.
- ANY, SOME 연산자
- 서브쿼리의 출력결과와 하나이상의 조건이 만족하면 참이 된다.
-
any 는 찾아진 값에 대해서 하나라도 크면 참이 된다.(최소값)
- EXIST 연산자 - 서브쿼리의 결과중에서 만족하는 값이 하나라도 존재하면 참이 된다.
[문제] 급여를 3000이상 받는 사원이 소속된 부서와 동일한 부서에서 근무하는 사원들의 정보를 출력하세요.
SQL>select ename, sal, deptno
from emp
where deptno in (select deptno
from emp
where sal >= 3000
);
[문제] 부서별로 가장 급여를 많이 받는 사원의 정보를 출력하세요.
SQL>select empno, ename, sal, deptno
from emp
where sal in (
select max(sal)
from emp
group by deptno
);
[문제] 영업사원들보다 급여를 많이 받는 사원들의 이름과 급여를 출력하되 영업사원은 출력하지 않게 명령문을 작성해보세요.
SQL>select ename, sal
from emp
where sal > all ( select sal
from emp
where job='SALESMAN'
);
부서 번호가 30번인 사원들의 급여 중 가장 낮은 값(950)보다 높은 급여를 받는 사원의 이름, 급여를 출력하는 명령문을 작성해 보세요.
[단일행 서브쿼리 & 그룹함수]
SQL>select ename, sal
from emp
where sal > ( select min(sal)
from emp
where deptno = 30
);
[다중행 서브쿼리]
SQL>select ename, sal
from emp
where sal > any (
select sal
from emp
where deptno = 30
);
[문제] 영업 사원들의 최소 급여보다 많이 받는 사원들의 이름과 급여와 직급을 출력하되 영업 사원은 출력하지 않습니다.
SQL>select ename, sal, job
from emp
where sal > any (
select sal
from emp
where job='SALESMAN'
)
and job <> 'SALESMAN';
##연습 문제
- 10번 부서 소속의 사원 중에서 커미션을 받는 사원의 수를 구해보세요.
- select count(*) from emp where deptno=10 and comm > 0;
- 가장 최근에 입사한 사원의 입사일과 입사한 지 가장 오래된 사원의 입사일을 출력해보세요.
- select max(hiredate) “최근입사일”, min(hiredate) “오래된 입사일” from emp ;
- SCOTT과 동일한 근무지에서 근무하는 사원의 이름을 출력하세요.
- select ename from emp where deptno=(select deptno from emp where ename=’SCOTT’);
- select e.ename from emp e, emp d where e.deptno=d.deptno and d.ename=’SCOTT’;
- 직급이 ‘SALESMAN’인 사원이 받는 급여들의 최소 급여보다 많이 받는 사원들의 이름과 급여를 출력하되
부서 번호가 20번인 사원은 제외한다.
- select ename, sal from emp where sal > any (select sal from emp where job=’SALESMAN’) and deptno<>20;
- 직급이 ‘SALESMAN’인 사원이 받는 급여들의 최대 급여보다 많이 받는 사원들의 이름과 급여를 출력하되
부서번호가 10번인 사원은 제외한다.
- select ename, sal from emp where sal > all (select sal from emp where job=’SALESMAN’) and deptno<>10;
- 사원테이블(emp)과 부서 테이블(dept)을 join하여 사원 이름과 부서번호와 부서명을 출력하세요.
단 40번 부서의 부서 이름도 출력 되도록 하세요.
- select ename, d.deptno, dname from emp e, dept d where e.deptno(+)=d.deptno;
- 뉴욕에서 근무하는 사원의 이름과 급여를 출력하세요(join 이용)
- select ename, sal from emp e, dept d where e.deptno=d.deptno and loc=’NEW YORK’;
- select ename, sal from emp inner join dept using(deptno) where loc=’NEW YORK’;
- select ename, sal from emp natural join dept where loc=’NEW YORK’;