728x90
반응형
SMALL

2절. 데이터 가공

* 종류

1) head(데이터셋), tail(데이터셋) 

- 시작 또는 마지막 6개 record만 조회

2) summary(데이터셋)

- 수치형 변수 : 최댓값, 최솟값, 평균, 1사분위수, 2사분위수(중앙값), 3사분위수

- 명목형 변수 : 명목값, 데이터 개수

1. 변수의 구간화

- 신용평가 모형, 고객 세분화 등의 시스템으로 모형을 적용하기 위해서 각 변수들을 구간화하여 점수를 적용하는 방식 활용

- 변수의 구간화를 위한 rule이 존재함

(** 10진수 단위로 구간화하고, 구간을 보통 5개로 나누며, 7개 이상의 구간은 잘 만들지 않음)

 

2. 변수 구간화의 방법

Binning 연속형 변수를 범주형 변수로 변환하기 위해 50개 이하의 구간에 동일한 수의 데이터를 할당하여 의미를 파악하면서 구간을 축소하는 방법
의사결정나무 모형을 통해 연속형 변수를 범주형 변수로 변환하는 방법

 

3절. 기초 분석 및 데이터 관리

1. 결측값 처리

1) 변수에 데이터가 비어있는 경우: NA, ., 99999999, Unknown, Not Answer  등

2) 단순대치법(Single Imputation)

Completes Analysis 결측값의 레코드를 삭제
평균대치법 관측 및 실험을 토애 얻어진 데이터의 평균으로 대치
* 비조건부 평균 대치법 : 관측 데이터의 평균으로 대치
* 조건부 평균 대치법 : 회귀분석을 통해 데이터를 대치
 단순확률 대치법 평균대치법에서 추정량 표준 오차의 과소 추정문제를 보완한 방법으로 Hot-Deck / Nearest Neighbor방법이 있음

3) 다중 대치법(Multiple Imputation) : 단순 대치법을 m번 실시하여, m개의 가상적 자료를 만들어 대치하는 방법

 

2. R의 결측값 처리 관련 함수

complete.cases() 데이터 내 레코드에 결측값이 있으면 FALSE, 없으면 TRUE반환
is.na() 결측값이 NA인지의 여부를 TRUE / FALSE로 반환
DMwR 패키지
: centralImputation()
NA 값을 가운데 값으로 대치(숫자 - 중위수, Factor - 최빈값)
DMwR 패키지
: knnImputation()
NA값을 k최근 이웃 분류 알고리즘을 사용하여 대치
(k개 주변 이웃까지의 거리를 고려하여 가중 평균한 값을 사용)
Amelia 패키지
: amelia()
time-series-cross-sectional data set에서 활용

3. 이상값 처리

1) 이상값

- 의도하지 않은 현상으로 입력된 값 or 의도된 극단값 -> 활용가능

- 잘못 입력된 값 or 의도하지 않은 현상으로 입력된 값이지만 분석 목적에 부합되지 않는 값 -> Bad Data이므로 제거

 

2) 이상값의 인식

- ESD(Extreme Studentized Deviation) : 평균으로부터 3 표준편차 떨어진 값

- 기하평균 - 2.5 * 표준편차 < data < 기하평균 + 2.5 * 표즌편차

- Q1 - 1.5*IQR < data < Q3 + 1.5 * IQR을 벗어나는 데이터(사분위수 이용해 제거)

 

3) 이상값(극단값)의 처리

- 절단 : 이상값이 포함된 레코드를 삭제

- 조정 : 이상값을 상한 또는 하한 값으로 조정

728x90
반응형
LIST
728x90
반응형
SMALL

조인이란?

- 하나 이상의 테이블로부터 데이터를 질의하기 위해 조인을 사용

- WHERE 절에 조인 조건 사용

- 하나 이상의 테이블에 똑같은 열 이름이 있을 때 열 이름 앞에 테이블 이름을 붙임

- 오라클 조인과 ANSI JOIN이 있음.

 

오라클 JOIN

SELECT table1.column, table2.column
FROM table1, table2
WHERE table1.column1 = table2.column;

 

1. CARTESIAN PRODUCT

- 조인 조건이 생략된 경우

- 조인 조건이 잘못된 경우

- 첫 번째 테이블의 모든 행이 두 번째 테이블의 모든 행과 조인되는 경우

SELECT table1.col, table2.col
FROM table1, table2;
--카티션프로덕트발생(조인 조건이 없기 때문)

2. EQUI JOIN

- 2개 이상의 테이블이 공통된 열에 의해 논리적 결합하는 조인 기법

- WHERE 절에 사용된 열들이 동등연산자(=) 에 의해 비교

select e.first_name, e.department_id, d.department_name
from employees e, departments d
where e.department_id = d.department_id;

 

3. SELF JOIN

- 자체적 테이블 조인

select e.first_name, m.first_name
from employees e, employees m
where e.manager_id = m. employee_id and e.employee_id=103;

 

4. NON-EQUI JOIN

- equal 연산자(=)로 조인하지 않음

select e.first_name, e.salary, j.job_title
from employees e, jobs j
where e.salary
between j.min_salary and j.max_salary
order by e.first_name;

 

5. OUTER JOIN

- 조인 조건을 만족하지 않는 행들도 보기 위해서 Outer 조인을 사용함

- Outer 조인 연산자는 더하기 기호(+) 임.

SELECT table.column, table.column
FROM table1, table2
WHERE table1.column(+) = table2.column;

SELECT table.column, table.column
FROM table1, table2
WHERE table1.column = table2.column(+);
select e.employee_id, e.first_name, e.hire_date,
j.start_date, j.end_date, j.job_id, j.department_id
from employees e, job_history j
where e.employee_id = j.employee_id
order by j.employee_id;

안시 조인

- 오라클 9i 버전부터 ANSI SQL 표준 문법 사용이 가능

- 조인의 형태가 FROM절에서 지정되며, 조인 조건이 ON 절 또는 USING 절에 표시

SELECT t1.col, t2, col
FROM t1
[LEFT|RIGHT|FULL][OUTER] JOIN t2
ON jooin_conditions
[WHERE conditions];

 

1. CROSS JOIN

- 두 개의 테이블에 대한 Cartesian Product와 같은 결과 출력

SELECT table1.column1, table2.column2
FROM table1
CROSS JOIN table2;
select employee_id, department_name
from employees
cross join departments;

 

 

2. NATURAL JOIN

- 모든 같은 이름을 갖는 열들에 대해 조인

- 지정해주지 않아도 자동으로 같은 이름가진 열에 대해 Equi조인을 수행한다.

SELECT table1.column1, table2.column2
FROM table1
NATURAL JOIN talbe2;
select first_name, job_title
from employees
natural join jobs;

 

3. USING JOIN

- using 절을 이용하여 원하는 열에 대해서만 선택적으로 Equi 조인을 할 수 있음.

SELET table1.column1, table2.column2
FROM table1
JOIN table2
USING (column);
select first_name, department_name
from employees
join departments
using (department_id);

 

4. ON JOIN

- on을 이용해 where에 들어갈 조인 조건을 적을 수 있음

SELECT table1.column1, table2.column2
FROM table1
JOIN table2
ON join_condition;
select department_name, street_Address, city, state_province
from departments d
join locations l
on d.location_id = l.location_id;

1) 여러 테이블의 조인

select e.first_name, d.department_name,
l.street_address || ', ' || l.city || ', '||
l.state_province as address
from employees e
join departments d on e.department_id = d.department_id
join locations l on d.location_id = l.location_id;

2) WHERE 절과의 혼용

select e.first_name as name,
d.department_name as department
from employees e
join departments d
on e.department_id = d.department_id
where employee_id = 103;

select e.first_name, d.department_name,
l.street_address || ', ' || l.city || ', '||
l.state_province as address
from employees e
join departments d on e.department_id = d.department_id
join locations l on d.location_id = l.location_id
where employee_id=103;

 

3) ON절에 WHERE절의 조건 추가

select e.first_name as name,
d.department_name as department
from employees e
join departments d
on e.department_id = d.department_id and employee_id = 103;

select e.first_name, d.department_name,
l.street_address || ', ' || l.city || ', '||
l.state_province as address
from employees e
join departments d on e.department_id = d.department_id
join locations l on d.location_id = l.location_id and employee_id=103;

 

5. OUTER JOIN

SELECT table1.column, table2.column
FROM table1
[LEFT|RIGHT|FULL][OUTER]JOIN table2
ON join_conditions
select e.employee_id, e.first_name, e.hire_date,
j.start_date, j.end_date, j.job_id, j.department_id
from employees e
left outer join job_history j
on e.employee_id = j.employee_id
order by e.employee_id;

1) LEFT OUTER JOIN

- 왼쪽의 테이블이 기준

select department_name, first_name 
from departments d
left join employees e
on d.manager_id = e.employee_id;

 

2) RIGHT OUTER JOIN

- 오른쪽 테이블이 기준

select department_name, first_name 
from employees e
right join departments d
on d.manager_id = e.employee_id;

 

3) FULL OUTER JOIN

- 왼쪽 오른쪽 모두 기준

728x90
반응형
LIST

'IT > SQL' 카테고리의 다른 글

[SQL] 8. 데이터 조작(DML)  (0) 2023.05.15
[SQL] 7. 서브쿼리(Subquery)  (0) 2023.05.12
[SQL] 5. 분석 함수  (0) 2023.05.11
[SQL] 4. 그룹 함수를 이용한 데이터 집계  (0) 2023.05.10
[SQL] 3. 함수 - 2  (0) 2023.05.09
728x90
반응형
SMALL

분석 함수

- 개발 생산성 높임-빨리 응답

- SQL 튜닝으로 성능을 높임

- 쿼리를 간단하게 하여 가독성 높임

- DW 분야에 사용

- SELECT절에서 사용

Anlytic_Funtion
	OVER ( PARTITION BY column_list
    		ORDER BY column_list [ASC|DESC]
            Windowing)

* PARTITION BY : 열의 행을 그룹화. 분석 함수로 계산될 대상 행의 그룹을 지정.

* ORDER BY : 정렬 (가장 많이 사용). 파티션 안에서의 순서를 지정.

* Windowing : 윈도우 절. 파티션으로 분할 그룹화 된 그룹에 대해 더 상세한 그룹으로 분할 할 때 사용

 

1. 순위 구하기 함수 - RANK, DENSE_RANK, ROW_NUMBER

RNAK 순위 결정(중복순위 계산o)
같은 값이면 1,2,2,4위 순
DENSE_RANK 순위 결정(중복순위 계산x)
같은 값이면 1,2,2,3,4위 순
ROW_NUMBER 조건을 만족하는 모든 행의 번호를 제공
- select절에서 순서를 매기기 때문에
- order by로 정렬을 하면 순서가 바뀔 수 잇음
- DB에 데이터가 물리적으로 저장된 순서에 따라 다름.
select employee_id, department_id, salary,
rank() over(order by salary desc) sal_rank,
dense_rank() over(order by salary desc) sal_dense_rank,
row_number() over(order by salary desc) sal_number
from employees;

 

2. 가상순위와 분포 - CUME_DIST, PERCENT_RANK

CUME_DIST 최대값 1을 기준으로 분산된 값 제공. 첫번째 0이 아님.
PERCENT_RANK 최대값 1을 기준으로 백분율 값 제공. 첫번째는 0
select employee_id, department_id,salary,
cume_dist() over(order by salary desc) sal_cume_dist,
percent_rank() over(order by salary desc) sal_pct_rank
from employees;

 

3. 비율 함수 - RATIO_TO_REPORT

RATIO_TO_REPORT 해당 컬럼 값의 총 값 중 차지하는 비율을
백분율로 표현. 소수점으로 제공
select first_name, salary,
round(ratio_to_report(salary) over(), 4) as salary_ratio
from employees
where job_id ='IT_PROG';

 

4. 분배 함수 - NTILE

NTILE 전체 데이터의 분포를 n개의 구간으로 나누어 표시
만약 45명을 10개씩 나누면 4.5이므로 앞쪽부터 하나씩 더 가져감
select employee_id, department_id, salary,
ntile(10) over(order by salary desc) sal_quart_tile
from employees
where department_id='50';

 

5. LAG, LEAD

- 윈도우 구간 지정

LAG 윈도우의 이전 n번째 행의 값을 가져옴
LAG(salary,2,0) : salary에서 현재 행 이전 2번째 행의 값을 가져오고
값이 없으면 0 출력.
LEAD 윈도우의 이후 n번째 행의 값을 가져올 수 있음
- LEAD(hire_date, 1,0) : 현재 행 기준 다음 입사일 값을 가져오고 없으면 0 출력
select employee_id,
lag(salary,1,0) over(order by salary) as lower_sal,
salary,
lead(salary,1,0) over(order by salary) as higher_sal
from employees
order by salary;

6. LISTAGG

LISTAGG(expression, 'delimiter')
	WITHIN GROUP(ORDER BY column)
LISTAGG 함수의 expression을 delimiter로 연결해 여러 행을 하나의 행으로 변환해 출력하는 함수
select department_id, first_name
from employees
group by department_id;
--에러
select department_id, 
listagg(first_name,', ') within group(order by hire_date)
from employees
group by department_id;

 

 

윈도우 절

- 파티션으로 분할된 그룹에 대해 다시 그룹을 만드는 역할

{rows|range}
	{BETWEEN {
    	UNBOUNDED PRECEDING
        | CURRENT ROW
        | value_expr{PRECEDING|FOLLOWING}
    }
    AND {
    	UNBOUNDED FOLLOWING
        | CURRENT ROW
        | value_expr{PRECEDING|FOLLOWING}
    }
   |{UNBOUNDED PRECEDING
   	| CURRENT ROW
   	| value_Expr PRECEDING
    	}
    }
순위(RANK) RANK, DENSE_RANK, ROW_NUMBER
집계(AGGREGATE) SUM, MAX, MIN, AVG, COUNT
순서(ORDER) LAG, LEAD, FIRST_VALUE, LAST_VALUE
그룹 내 비율(RATIO) CUME_DIST, PERCENT_RANK, RATIO_TO_REPORT, NTILE
통계분석(ANALYTICS) CORR, COVAR_POP, COVAR_SAMP, STDDEV, STDDEV_POP, STDDEV_SAMP, VARIANCE, VAR_POP, VAR_SAMP
rows 데이터를 물리적 위치로 구분해 모든 행을 한 행으로 인식
range 논리적으로 구성하며 값이 같으면 묶어서 한 행으로 인식

1. 윈도우 절 사용

select department_id, first_name, salary,
sum(salary) over(partition by department_id
order by salary
rows between unbounded preceding
and current row) as sum_rows
from employees;

select department_id, first_name, salary,
sum(salary) over(partition by department_id
order by salary
range between unbounded preceding
and current row) as sum_rows
from employees;

 

선형 회귀 함수

{REGR_SLOPE | REGR_INTERCEPT | REGR_COUNT | REGR_R2 |
REGR_AVGX | REGR_AVGY | REGR_SXX | REGR_SYY | REGR_SXY}
(y,x)
	[OVER (analytic_clause)]

 

 

1. REGR_AVGX(y,x), REGR_AVGY(y,x)

- 각 함수의 첫 번째 인수인 x,y가 null이면 계산에 포함하지 않는다.

select avg(salary), regr_avgx(commission_pct, salary), regr_avgy(commission_pct, salary)
from employees;

 

 

2. REGR_COUNT(y,x)

- 두 인수의 값이 not null인 쌍 수를 계산

select distinct department_id,
regr_count(manager_id, department_id)
over (partition by department_id) "REGR_COUNT"
from employees
order by department_id;

 

3. REGR_SLOPE(y,x), REGR_INTERCEPT(y,x)

* slope: 회귀 직선의 기울기 측정(weight)

- COVAR_POP(y,x) / VAR_POP(x)

*intercept : 회귀 직선의 y절편(bias)

- AVG(y) - REGR_SLOPE(y,x) * AVG(x)

select
job_id, employee_id, salary,
round(sysdate-hire_date) "working_day",
round(regr_slope(salary, sysdate-hire_date)
over(partition by job_id),2) "regr_slope",
round(regr_intercept(salary, sysdate-hire_date)
over(partition by job_id),2) "regr_intercept"
from employees
where department_id = 80
order by job_id, employee_id;

 

4. REGR_R2

- 회귀 분석에 대한 결정 계수(얼마나 잘 표현했냐)를 반환

- 적합도

- 종속 변수와 독립변수 사이에 상관관계가 높을수록 1에 가까워짐.

* 반환값

- VAR_POP(x) = 0 이면 null

- VAR_POP(y) =0 이고 VAR_POP(x) !=0이면 1

- VAR_POP(y) > 0 이고 VAR(x) !=0 이면 POWER(CORR(y,x),2)

select
distinct
job_id,
round(regr_slope(salary, sysdate-hire_date)
over(partition by job_id),2) "regr_slope",
round(regr_intercept(salary, sysdate-hire_date)
over(partition by job_id),2) "regr_intercept",
round(regr_r2(salary, sysdate-hire_date)
over(partition by job_id),2) "regr_r2"
from employees
where department_id=80;

=> 두 회귀모형 중 SA_MAN이 SA_REP보다 유용성이 더 높다고 판단할 수 있다.

 

피벗 테이블

 

1. 관계형 데이터베이스 형식과 스프레드시트 형식

create table sale_log(
employee_id number(6),
week_id number(2),
week_day varchar(10),
quantity number(8,2)
);

insert into sale_log values(1101, 4 , 'sales_mon', 100);
insert into sale_log values(1101, 4 , 'sales_tue', 150);
insert into sale_log values(1101, 4 , 'sales_wed', 80);
insert into sale_log values(1101, 4 , 'sales_thu', 60);
insert into sale_log values(1101, 4 , 'sales_fri', 120);

insert into sale_log values(1102, 5 , 'sales_mon', 300);
insert into sale_log values(1102, 5 , 'sales_tue', 300);
insert into sale_log values(1102, 5 , 'sales_wed', 230);
insert into sale_log values(1102, 5 , 'sales_thu', 120);
insert into sale_log values(1102, 5 , 'sales_fri', 150);
commit;
select * from sale_log;

create table sales(
employee_id number(6),
week_id number(2),
sales_mon number(8,2),
sales_tue number(8,2),
sales_wed number(8,2),
sales_thu number(8,2),
sales_fri number(8,2)
);

insert into sales values(1101,4,100,150,80,60,120);
insert into sales values(1102,5,300,300,230,120,150);
commit;
select * from sales;

 

2. PIVOT

SELECT col1, col2, ...var_col1, ... var_coln
FROM tables
PIVOT
(
	aggregate_function(value_column)
    FOR variable_column
    IN(expr1 [[AS] var_col1], ... , expr_n [[AS] var_coln])
)
WHERE conditions
ORDER BY expression [ASC | DESC];
select * from sale_log
pivot(
sum(quantity)
for week_day in(
'sales_mon' as sales_mon,
'sales_tue' as sales_tue,
'sales_wed' as sales_wed,
'sales_thu' as sales_thu,
'sales_fri' as sales_fri
)
)
order by employee_id, week_id;

 

3. UNPIVOT

SELECT col1, ... , variable_column, value_column
FROM tables
UNPIVOT(
	value_column
    FOR variable_column
    IN(expr1, expr2, ..., expr_n)
)
WHERE conditions
ORDER BY expression [ASC | DESC];
select employee_id, week_id, week_day, quantity
from sales
unpivot
(
quantity
for week_day
in(sales_mon, sales_tue, sales_wed, sales_thu, sales_fri)
);

728x90
반응형
LIST

'IT > SQL' 카테고리의 다른 글

[SQL] 7. 서브쿼리(Subquery)  (0) 2023.05.12
[SQL] 6. 조인을 이용한 다중 테이블 검색  (0) 2023.05.11
[SQL] 4. 그룹 함수를 이용한 데이터 집계  (0) 2023.05.10
[SQL] 3. 함수 - 2  (0) 2023.05.09
[SQL] 3. 함수 - 1  (0) 2023.05.09
728x90
반응형
SMALL

그룹함수

1. AVG, SUM, MIN, MAX(평균, 합, 최소, 최대값)

select avg(salary),sum(salary),min(salary),max(salary)
from employees
where job_id like 'SA%';
select min(hire_date), max(hire_date)
from employees;
-- 날짜로 min,max가능

select min(first_name), max(last_name)
from employees;

select max(salary)
from employees;

2. COUNT

count(*)
count(expr)
select count(*) from employees;
select count(commission_pct) from employees;

 

3. STDDEV, VARIANCE

select sum(salary) as 합계,
round(avg(salary),2) as 평균,
round(stddev(salary),2) as 표준편차,
round(variance(salary),2) as 분산 
from employees;

4. 그룹 함수와 NULL 값

- count(*)를 제외한 모든 그룹 함수는 열에 있는 NULL값을 연산에서 제외

select
round(sum(salary*commission_pct),2) as sum_bonus,
count(*) count,
round(avg(salary*commission_pct),2) as avg_bonus1,
round(sum(salary*commission_pct)/count(*),2) as avg_bonus2
from employees;

select avg(nvl(salary*commission_pct,0))
from employees;

 

GROUP BY

SELECT column, group_function(column)
FROM table
[WHERE condition(S)]
[GROUP BY group_by_expression]
[ORDER BY {column | expr[[ASC]|DESC],...};

 

1. GROUP BY 사용

select department_id, avg(salary)
from employees
group by department_id;

2. 하나 이상의 열로 그룹화

select department_id, job_id, sum(salary)
from employees
group by department_id, job_id;

3. 그룹 함수를 잘못 사용한 질의

- select 절의 그룹 함수가 아닌 모든 열이나 표현식은 group by 절에 있어야 한다.

- where 절을 사용해 그룹을 제한할 수 없다. having 사용

 

HAVING

- 그룹 제한하기 위해 사용

SELECT coulmn, group_function(column)
FROM table
[WHERE condition(s)]
[GROUP BY group_by_expression]
[HAVING group_condition]
[ORDER BY {column|expr[[ASC]|DESC]]}];

1. HAVING 사용

select department_id, avg(salary)
from employees
group by department_id
having avg(salary) > 2000;

select job_id, avg(salary) payroll
from employees
where job_id not like 'SA%'
group by job_id
having avg(salary) > 8000
order by avg(salary) desc;

 

GROUPING SETS

SELECT coulmn, group_function(column)
FROM table
[WHERE condition(s)]
[GROUP BY [GROUPING SETS] (group_by_expression)]
[HAVING group_condition]
[ORDER BY {column|expr[[ASC]|DESC]]}];
select department_id, job_id, round(avg(salary),2)
from employees
group by grouping sets(department_id, job_id)
order by department_id, job_id;

select department_id, job_id, manager_id, round(avg(salary),2) as avg_Sal
from employees
group by grouping sets((department_id, job_id),
(job_id, manager_id))
order by department_id, job_id, manager_id;

 

ROLLUP, CUBE

1. ROLLUP, CUBE사용

select department_id,job_id, round(Avg(salary),2), count(*)
from employees
group by department_id, job_id
order by department_id, job_id;
--각 부서의 직업별 평균만 알 수 있다.
--각 부서의 전체 평균을 알고싶다면 rollup사용
select department_id,job_id, round(Avg(salary),2), count(*)
from employees
group by rollup(department_id, job_id)
order by department_id, job_id;

- 여기에 직무별 평균과 사원의 수도 출력하고 싶으면 cube 사용

select department_id,job_id, round(Avg(salary),2), count(*)
from employees
group by cube(department_id, job_id)
order by department_id, job_id;

 

GROUPING

- ROLLUP, CUBE, GROUPING SETS 등 GROUP BY 확장 연산으로 소계의 일부로 생성된 null값일 경우 1을 반환

- 저장된 null값이거나 다른 값일 경우 0 반환

select
decode(grouping(department_id), 1, '소계',
to_Char(department_id)) as 부서,
decode(grouping(job_id),1,'소계',job_id) as 직무,
round(avg(salary),2) as 평균,
count(*) as 사원의수
from employees
group by cube(department_id, job_id)
order by 부서, 직무;

 

GROUPING_ID

- GROUPING_ID는 행과 연관된 GROUPING 비트 벡터에 해당하는 숫자를 반환

- GROUPING_ID를 사용하면 그룹화 수준 식별 가능

GROUPING_ID(column, column2,...)
select
decode(grouping_id(department_id, job_id),
2, '소계', 3, '합계',
to_char(department_id)) as 부서번호,
decode(grouping_id(department_id, job_id),
1,'소계',3,'합계',
job_id) as 직무,
grouping_id(department_id, job_id) as gid,
round(avg(salary),2) as 평균,
count(*) as 사원수
from employees
group by cube(department_id, job_id)
order by 부서번호, 직무;

728x90
반응형
LIST

'IT > SQL' 카테고리의 다른 글

[SQL] 6. 조인을 이용한 다중 테이블 검색  (0) 2023.05.11
[SQL] 5. 분석 함수  (0) 2023.05.11
[SQL] 3. 함수 - 2  (0) 2023.05.09
[SQL] 3. 함수 - 1  (0) 2023.05.09
[SQL] 2. SELECT문  (0) 2023.05.08
728x90
반응형
SMALL

변환 함수

* 암시적인 데이터형 변환

* 명시적인 데이터형 변환

 

1. 암시적 형 변환

- 값 할당 시 오라클은 자동으로 변환한다.

From To 비고
VARCHAR2 / CHAR NUMBER 표현식 계산의 경우
VARCHAR2 / CHAR DATE 표현식 계산의 경우
NUMBER VARCHAR2  
DATE VARCHAR2  
select employee_id, first_name, hire_date
from employees
where hire_date='03/06/17';
--char가 DATE형으로 변환
select employee_id, first_name, department_id
from employees
where department_id='40';
--char가 NUMBER타입으로 자동 형 변환

 

2. 명시적 형 변환

변환 함수 설명
TO_CHAR(number [, 'fmt']) 숫자를 문자 타입으로
TO_CHAR(date[, 'fmt']) 날짜를 문자 타입으로
TO_NUMBER(char[, 'fmt']) 숫자를 포함하 문자를 숫자로
TO_DATE(char[, 'fmt']) 날짜를 나타내는 문자를 DATE타입으로

 

3. 날짜를 문자로 변환

TO_CHAR(date, 'fmt')
select first_name, TO_CHAR(hire_date, 'MM/YY') as hiremonth
from employees
where first_name='Steven';

select first_name, to_char(hire_date, 'YYYY"년" MM"월" DD"일"') as hiredate
from employees;

select first_name,to_char(hire_date, 'fmDdspth "of" Month YYYY fmHH:MI:SS AM',
'NLS_DATE_LANGUAGE=english') as hiredate from employees;

 

4. 숫자를 문자로 변환

TO_CHAR(number, 'fmt')
select first_name, last_name,to_char(salary, '$999,999') salary
from employees;

select first_name, last_name, salary*0.123456 salary1,
to_char(salary*0.123456, '$999,999.99') salary2
from employees
where first_name='David';

5. TO_NUMBER 함수

TO_NUMBER(char, 'fmt')
select '$5,500'-4000 from dual; --오류
select to_number('$5,500', '$999,999')-4000 from dual;

 

6. TO_DATE 함수

TO_DATE(char, 'fmt')
select first_name, hire_date
from employees
where hire_date=to_date('2003/06/17','YYYY/MM/DD');

select first_name, hire_date
from employees
where hire_date = to_date('2003년06월17일', 'YYYY"년"MM"월"DD"일"');

7. Null 치환 함수 NVL, NVL2, COALESCE

1) NVL1

NVL(expr1, expr2)
--expr1:널이 있을 수 있는 열
--expr2:널일경우 치환할 값
select first_name, salary + salary*nvl(commission_pct,0) from employees;

2) NVL2

nvl2(expr1, expr2, expr3)
select first_name,
nvl2(commission_pct, salary+salary*commission_pct, salary) as nann_sal
from employees;

3) COALESCE

COALESCE(expr1, ...)
select first_name,
coalesce(salary+salary*commission_pct, salary)as ann_sal
from employees;

 

 

8. 기타 변환 함수

1) LNNVL 

LNNVL(expr1)
select first_name, coalesce(salary*commission_pct,0) as bonus from employees
where salary*commission_pct < 650;

==>null인 것들을 모두 제외하게 됨

select first_name, coalesce(salary*commission_pct,0) as bonus from employees
where lnnvl(salary*commission_pct >= 650);

=>null값도 포함시킴

 

2) DECODE

select job_id, salary, 
decode(job_id, 'IT_PROG', salary*1.10,
'FI_MGR', salary*1.15,
'FI_ACCOUNT', salary*1.20,
salary) as revised_sal
from employees;

 

3) CASE

select job_id, salary,
case job_id when 'IT_PROG' then salary*1.10
when 'FI_MGR' then salary*1.15
when 'FI_ACCOUNT' then salary*1.20
else salary
end as revise_sal
from employees;

=>위와 같은 결과

select employee_id, salary,
case when salary < 5000 then salary*1.2
when salary < 10000 then salary*1.10
when salary < 15000 then salary*1.05
else salary
end as revised_sal
from employees;

 

집합 연산자

1. UNION

- 합집합과 같은 의미

- 중복된 정보는 한 번만 보여줌.

select employee_id, first_name from employees where hire_date like '04%'
union
select employee_id, first_name from employees where department_id=20;

 

2. UNION ALL

- 중복된 정보 포함

select employee_id, first_name from employees where hire_date like '04%'
union all
select employee_id, first_name from employees where department_id=20;

 

3. INTERSECT

- 중복된 행만 출력

- 교집합과 같은 의미

select employee_id, first_name from employees where hire_date like '04%'
intersect
select employee_id, first_name from employees where department_id=20;

 

4. MINUS

- 첫번째 쿼리에만 포함되고 두번째 쿼리에는 없는 데이터를 보여준다.

- 차집합과 같은 의미

select employee_id, first_name from employees where hire_date like '04%'
minus
select employee_id, first_name from employees where department_id=20;

 

728x90
반응형
LIST

'IT > SQL' 카테고리의 다른 글

[SQL] 5. 분석 함수  (0) 2023.05.11
[SQL] 4. 그룹 함수를 이용한 데이터 집계  (0) 2023.05.10
[SQL] 3. 함수 - 1  (0) 2023.05.09
[SQL] 2. SELECT문  (0) 2023.05.08
[SQL] 1. 데이터베이스 소개  (0) 2023.05.08
728x90
반응형
SMALL

함수

1. SQL 함수 개요

- 함수 : 데이터를 조작하기 위해 사용됨.

- 특징 :

1) 데이터 계산 수행

2) 개별적인 데이터 항목 수정

3) 행의 그룹에 대해 결과 조작

4) 출력을 위한 날짜와 숫자 형식 설정

5) 열의 데이터 타입 반환

2. SQL 함수의 두 가지 유형

* 단일행 함수

- 오직 단일행에서만 적용 가능하고 행별로 하나의 결과를 반환

 

* 다중행 함수

- 복수의 행을 조작하여 행의 그룹 당 하나의 결과를 반환

 

3. 단일 행 함수

function_name(column | expression, [arg1, arg2, ...])

- 데이터 값 조작

- 인수(argument)를 받고 하나의 결과 리턴

- 리턴될 각각의 행에 적용

- 행별로 하나의 결과 리턴

- 데이터 타입 수정 가능

- 중첩(nested)될 수 있다.

- 종류 : 문자/숫자/날짜/변환/General 함수

 

문자 함수

select initcap('helloworld') from dual;

1. LOWER, INITCAP, UPPER

select last_name, lower(last_name), initcap(last_name), upper(last_name)
from employees;
select last_name, lower(last_name), initcap(last_name), upper(last_name)
from employees
where lower(last_name)='austin';

2. LENGTH, INSTR

select first_name, length(first_name),instr(first_name,'a')
from employees;

3. SUBSTR, CONCAT

select first_name, substr(first_name,1,3), concat(first_name, last_name)
from employees;

4. LPAD, RPAD

select rpad(first_name,10,'-') as name, lpad(salary,10,'*')as sal
from employees;

5. LTRIM, RTRIM

select ltrim('JavaSpecialist','Java') from dual;
select ltrim(' JavaSpecialist') from dual;
select trim( 'JavaSpecialist ') from dual;

6. REPLACE, TRANSLATE

select replace('JavaSpecialist','Java','BigData') from dual;
select replace('Java Specialist',' ','') from dual;
select translate('javaspecialist','abcdefghijklmnopqrstuvwxyz','defghijklmnopqrstuvwxyzabc') from dual;

7. 실전 문제

select rpad(substr(first_name,1,3),length(first_name),'*') as name,
lpad(salary,10,'*') as salary 
from employees
where lower(job_id) = 'it_prog';

 

정규표현식 함수

함수 명칭 설명
REGEXP_LIKE 패턴에 이리하는 문자열을 포함하는 행 찾기
LONG 지원X
REGEXP_INSTR 지정한 조건을 만족하는 부분의 최초의 위치를 돌려줌.
REGEXP_SUBSTR 지정한 정규 표현을 만족하는 부분 문자열 반환
REGEXP_REPLACE 지정한 정규 표현을 만족하는 부분을, 지정한 다른 문자열로 치환

1. 정규표현식

- 횟수 지정 메타 문자

메타 문자 기능
? 0회 또는 1회
* 0회 이상
+ 1회 이상
{n} n회 이상
{m,} m회 이상
{m,n} m회 이상 n회 이하

- 메타 문자

메타 문자 기능
. 문자
[] 문자들
[^ ] 부정
^ 처음
$
() 그룹 묶기

- 탈출 문자

탈출 문자 기능
\n n번째 패턴
\w "-"와 영숫자
\W \w 반대
\s 공백
\S 공백 제외
\d 숫자
\D 숫자 제외

- POSIX 문자클래스

문자 클래스 설명
   
   
   
   
   
   
   
   
   

 

2. REGEXP_LIKE 함수

REGEXP_LIKE(source_string, pattern[, match_parameter])
Create table test_regexp (col1 varchar2(10));
insert into test_regexp values('ABCDE01234');
insert into test_regexp values('01234ABCDE');
insert into test_regexp values('abcde01234');
insert into test_regexp values('01234abcde');
insert into test_regexp values('1-234-5678');
insert into test_regexp values('234-567890');

select * from test_regexp
where regexp_like(col1,'[0-9][a-z]');

select * from test_regexp
where regexp_like(col1,'[0-9]{3}-[0-9]{4}$');
select * from test_regexp
where regexp_like(col1,'[[:digit:]]{3}-[[:digit:]]{4}$');
select * from test_regexp
where regexp_like(col1,'^[0-9]{3}-[0-9]{4}');

 

create table qa_master (qa_no varchar(10));

alter table qa_master add constraint qa_no_chk check
(regexp_like(qa_no,
'^[[:alpha:]]{2}-[[:digit:]]{2}-[[:digit:]]{4}$'));

insert into qa_master values('QA-01-0001');
insert into qa_master values('00-01-0001'); --오류

 

3. REGEXP_INSTR 함수

REGEXP_INSTR(source_string, pattern [, start_position
[, occurrence [ , return_option [, match_parameter]]]])
insert into test_regexp values('@!=)(9&%$#');
insert into test_regexp values('자바3');

select col1,regexp_instr(col1,'[0-9]') as data1,
regexp_instr(col1,'%') as data2 from test_regexp;

4. REGEXP_SUBSTR 함수

REGEXP_SUBSTR(source_string, pattern [, start_position [, occurrence [, match_parameter]]])
select col1, regexp_substr(col1, '[C-Z]+') from test_regexp;

5. REGEXP_REPLACE 함수

regexp_replace(source_string, pattern [, replace_string [, start_position [, occurrence [, match_parameter]]]])
select col1, regexp_replace(col1,'[0-2]+','*')
from test_regexp;

 

6. 실전 문제

select first_name, phone_number
from employees
where regexp_like(phone_number,'[0-9]{3}.[0-9]{3}.[0-9]{4}$');

 

select first_name, 
regexp_replace(phone_number, '[0-9]{4}$','****') as phone,
regexp_substr(phone_number, '[0-9]{4}$') as phone2
from employees;

숫자 함수

1. ROUND, TRUNC

select round(45.923,2), round(45.923,0), round(45.923,-1) from dual;

select trunc(45.923,2), trunc(45.923), trunc(45.923,-1) from dual;

 

날짜 함수

select sysdate from dual;

1. 날짜의 연산

- 날짜에서 숫자를 더하거나 빼 날짜 결과를 반환

- 날짜 사이의 일(day) 수를 알기 위해 두 개의 날짜를 뺀다

- 시간을 24로 나누어 날짜에 더한다.

select first_name, (sysdate-hire_date)/7 as "weeks"
from employees
where department_id=60;

2. 날짜 함수

select first_name, sysdate, hire_date, months_between(sysdate, hire_date) as workmonth
from employees
where first_name='Diana';
select first_name, hire_Date, add_months(hire_date, 100)
from employees
where first_name='Diana';
select sysdate, next_day(sysdate,'월')
from dual;
select sysdate, last_day(sysdate) from dual;
select sysdate, round(sysdate), trunc(sysdate) from dual;
select sysdate, round(sysdate), trunc(sysdate) from dual;
select trunc(sysdate, 'Month') from dual;
select trunc(sysdate, 'Year') from dual;
select trunc(to_date('17/03/16'), 'Month') from dual;
select round(to_date('17/03/16'), 'Month') from dual;
select trunc(to_date('17/03/16'), 'Day') from dual;

 

 

 

 

728x90
반응형
LIST

'IT > SQL' 카테고리의 다른 글

[SQL] 5. 분석 함수  (0) 2023.05.11
[SQL] 4. 그룹 함수를 이용한 데이터 집계  (0) 2023.05.10
[SQL] 3. 함수 - 2  (0) 2023.05.09
[SQL] 2. SELECT문  (0) 2023.05.08
[SQL] 1. 데이터베이스 소개  (0) 2023.05.08
728x90
반응형
SMALL

SELECT 문장

1. SELECT

SELECT [DISTINCT] {* | coulumn[[AS] alias], ...}
FROM tablename;
SELECT 하나 이상의 열을 나열합니다.
DISTINCT 중복 제거
* 모든 열 선택
column 명명된 열 선택
AS 열 별칭(alias) 지정
alias 선택된 열을 다른 이름으로 변경
FROM tablename; 열을 포함하는 테이블 명시

 

2. SQL 문장 작성

- 대/소문자 구별X

- 문장이 한 줄 이상일 수 있음

- 키워드는 단축하거나 줄을 나눠 쓸 수 있음

- 절은 대개 줄을 나누어 작성

- 탭과 들여쓰기는 가독성을 위해 사용

SQL> SELECT first_name, last_name, salary
  2  FROM employees;

 

3. 모든 열 선택

SQL> SELECT *
  2  FROM departments;

 

4. 특정 열 선택

SQL> SELECT department_name, location_id
  2> FROM departments;

 

5. 기본 표시 형식

- 디폴트 데이터 자리맞춤을 지정합니다.

- 날짜와 문자 데이터는 왼쪽 정렬됩니다.

- 숫자 데이터는 오른쪽 정렬됩니다.

- 디폴트 열 헤딩은 대문자로 출력됩니다

 

6. 열 별칭(alias) 정의

- 열 헤딩 이름을 변경합니다.

- 계산할 때 유용

- 열 이름 바로 뒤에 두며 AS 별칭 으로 하기도 합니다.

- 공백/특수문자는 인용부호(" ")가 필요합니다.

SQL> SELECT first_name AS 이름, salary 급여
  2  FROM employees;

 

7. 리터럴(literal) 문자 스트링과 연결 연산자

- SELECT 절에 포함된 리터럴은 문자 표현식 또는 숫자 입니다.

- 날짜와 문자 리터럴 값은 단일 인용부호(' ')안에 있어야 합니다.

- 숫자 리터럴은 단일 인용부호(' ')를 사용하지 않습니다.

- 각각의 문자스트링은 리턴된 각 행에 대한 결과입니다.

- ||를 이용하면 값을 연결해 줍니다

SQL> SELECT first_name || ' ' || last_name || '''s salary is $' || salary
  2  AS	"Employee Details"
  3  FROM employees;

 

8. 중복 행과 DISTINCT

- 디폴트 출력은 중복되는 행을 포함하는 모든 행입니다.

- SELECT 절에서 DISTINCT 키워드를 사용하여 중복되는 행을 제거합니다.

 

데이저 제한

1. Selection

- 원하는 행을 선택적으로 조회하는 것

 

2. 선택된 행 제한

- WHERE 절을 사용하여 반환하는 행을 제한

- WHERE 절은 FROM절 다음에 위치

- WHERE 절은 열 이름, 비교 연산자, 비교할 열 이름 또는 값의 목록으로 구성

SELECT [DISTINCT] {*|coulumn[[AS] alis], ...}
FROM table
[WHERE condition(s)];
SELECT first_name, job_id, department_id
FROM employees
WHERE job_id = 'IT_PROG';

 

3. 문자와 날짜

- 문자, 문자열, 날짜는 ''로 둘러쌈.

- 문자 값은 대/소문자 구분, 날짜 값은 형식을 따른다.

- 기본 날짜 형식은 'DD-MON-YY'

SELECT first_name, hire_date
FROM employees
WHERE last_name='King';

 

 

4. 비교 연산자

연산자 설명
= 같다
> 크다
>= 크거나 같다
< 작다
<= 작거나 같다
<> , != 같지 않다

 

5. BETWEEN 연산자

- 값의 범위에 해당하는 값을 출려하기 위해 BEETWEEN 사용

- 하한값 먼저 명시

- 하한값, 상한값 모두 포함

-- 2004년에 입사한 사원
SELECT first_name, salary, hire_date
FROM employees
WHERE hire_date BETWEEN '04/01/01' AND '04/12/31';

6. IN 연산자

- 목록에 값이 있는지 비교

SELECT employee_id, first_name, salary, manager_id
FROM employees
WHERE manager_id IN(101, 102, 103);

 

7. LIKE 연산자

- 검색 문자열에 대한 와일드카드 검색

- 검색 조건은 문자, 날짜 포함 가능

- %는 문자가 없거나 하나 이상 문자들 대신

- _는 하나의 문자 대신

--LIKE연산
SELECT first_name, last_name, job_id, department_id
FROM employees
WHERE job_id LIKE 'IT_%';

 

8. IS NULL 연산자

- IS NULL 연산자로 널인지 테스트

- 널이 아닌 값은 IS NOT NULL

SELECT first_name, manager_id
FROM employees
WHERE manager_id IS NULL;

 

9. 논리 연산자

- AND는 양쪽 조건이 참이어야 TRUE 반환

- OR은 한쪽의 조건이 참이면 TRUE 반환

- NOT 연산자는 뒤의 조건에 반대되는 결과 반환

 

10. 논리 연산자 우선순위

우선순위 연산자
1 모든 비교 연산자
2 NOT
3 AND
4 OR

 

데이터 정렬

- 질의에 의해 검색되는 행을 정렬할 수 있다.

- ORDER BY 절은 SELECT 문장의 가장 뒤에 옴.

- ASC :오름차순

- DSEK : 내림차순

SELECT expr
FROM table
[WEHRE condition(s)]
[ORDER BY {coluumn|expr [[ASC]|DESC];
select first_name, hire_date
from employees
order by hire_date;

select first_name, hire_date from employees
order by hire_date desc;

select first_name, salary*12 as annsal
from employees
order by annsal;

select first_name, salary*12 as annsal
from employees
order by 2;

실습

1. 모든 사원의 사원번호, 이름, 입사일, 급여를 출력하세요.

2. 모든 사원의 이름과 성을 붙여 출력하세요. 열 별칭은 name으로 하세요.

3. 50번 부서 사원의 모든 정보를 출력하세요.

4. 50번 부서 사원의 이름, 부서번호, 직무아이디를 출력하세요.

5. 모든 사원의 이름, 급여 그리고 300달러 인상된 급여를 출력하세요.

6. 급여가 10000보다 큰 사원의 이름과 급여를 출력하세요.

7. 보너스를 받는 사원의 이름과 직무, 보너스율을 출력하세요.

8. 2003년도 입사한 사원의 이름과 입사일 그리고 급여를 출력하세요.(BETWEEN 연산자 사용)

9. 2003년도 입사한 사원의 이름과 입사일 그리고 급여를 출력하세요.(LIKE 연산자 사용)

10. 모든 사원의 이름과 급여를 급여가 많은 사원부터 적은 사원순서로 출력하세요.

11. 위 질의를 60번 부서의 사원에 대해서만 질의하세요.

12. 직무아이디가 IT_PROG 이거나, SA_MAN인 사원의 이름과 직무아이디를 출력하세요.

13. Steven King 사원의 정보를 “Steven King 사원의 급여는 24000달러 입니다” 형식으로 출력하세요.

14. 매니저(MAN) 직무에 해당하는 사원의 이름과 직무아이디를 출력하세요.

15. 매니저(MAN) 직무에 해당하는 사원의 이름과 직무아이디를 직무아이디 순서대로 출력하세요

 

--연습문제
---1
select employee_id, first_name, hire_date, salary
from employees;
--2
select first_name ||' '|| last_name as name
from employees;
--3
select * from employees where department_id=50;
--4
select first_name, department_id, job_id from employees where department_id=50;
--5
select first_name, department_id, salary, salary+300 from employees;
--6
select first_name, salary from employees where salary>10000;
--7
select first_name, job_id, commission_pct from employees
where commission_pct is not null;
--8
select first_name, hire_date,salary from employees
where hire_date between '03/01/01' and '03/12/31';
--9
select first_name,hire_date, salary
from employees
where hire_date like '03%';
--10
select first_name, salary from employees
order by salary desc;
--11
select first_name, salary from employees
where department_id=60
order by salary desc;
--12
select first_name, job_id
from employees
where job_id in('IT_PROG', 'SA_MAN');
--13
select first_name||' '||last_name||' 사원의 급여는 '||salary||'달러입니다.'
from employees
where last_name='King' and first_name='Steven';
--14
select first_name, job_id from employees
where job_id like '%MAN';
--15
select first_name, job_id from employees
where job_id like '%MAN'
order by job_id;
728x90
반응형
LIST

'IT > SQL' 카테고리의 다른 글

[SQL] 5. 분석 함수  (0) 2023.05.11
[SQL] 4. 그룹 함수를 이용한 데이터 집계  (0) 2023.05.10
[SQL] 3. 함수 - 2  (0) 2023.05.09
[SQL] 3. 함수 - 1  (0) 2023.05.09
[SQL] 1. 데이터베이스 소개  (0) 2023.05.08
728x90
반응형
SMALL

개요

1. 관계형 데이터베이스 역사

1.1 역사

- 1960년대 : Flat File

- 1970년대 : Network DBMS, Hierarchical DB

- 1980년대 : 관계형 DBMS

- 1990년대 : 관계형 DBMS, 객체 관계형 DBMS

- 2000년대 : 관계형/객체관계형/객체지향 DBMS

1.2 데이터베이스 시스템에 대한 관계형 모델 제안

- E.F.Codd 박사(1970년 6월)

- “A Relational Model of Data for Large Shared Data Banks” 라는 논문

- RDBMS(Relational Database Management System)의 시초

1.3 관계형 모델의 구성요소

- 개체(object) 혹은 관계(relation)의 집합

- 관계(relation)에 가해지는 연산자의 집합

- 정확성과 일관성을 위한 데이터 무결

 

2. 관계형 데이터베이스 정의

2.1 정의

- 관계형 데이터베이스는 관계들의 모음 또는 이차원 테이블의 모음이다.

2.2 파일 시스템과 데이터베이스 시스템의 차이점

- 데이터 무결성 제공

- 데이터 공유 가능

- 데이터 정확성과 일관성 제공

- 관계 설정을 통한 중복 제거

- 표준화가 가능

 

3. 관계형 데이터베이스 특징

- SQL을 이용한 데이터 조작

- 데이터 무결성 제공

- 트랜잭션 제공

- ACID 규정 준수 : 데이터베이스 트랜잭션이 안전하게 수행된다는 것을 보장하기 위한 성질을 가리키는 용어

원자성(Atomicity) 일관성(Consistency) 독립성(Isolation) 지속성(Durability)
- 트랜잭션과 관련된 작업들이 부분적으로 실행되다가 중단되지 않는 것을 보장하는 능력이다.
- 예를 들어, 자금 이체는 성공할 수도 실패할 수도 있지만 보내는 쪽에서 돈을 빼 오는 작업만 성공하고 받는 쪽에 돈을 넣는 작업을 실패해서는 안된다.
- 원자성은 이와 같이 중간 단계까지 실행되고 실패하는 일이 없도록 하는 것이다.
- 트랜잭션이 실행을 성공적으로 완료하면 언제나 일관성 있는 데이터베이스 상태로 유지하는 것을 의미한다.
- 무결성 제약이 모든 계좌는 잔고가 있어야 한다면 이를 위반하는 트랜잭션은 중단된다.
- 트랜잭션을 수행 시 다른 트랜잭션의 연산 작업이 끼어들지 못하도록 보장하는 것
- 트랜잭션 밖에 있는 어떤 연산도 중간 단계의 데이터를 볼 수 없음을 의미한다.
- 은행 관리자는 이체 작업을 하는 도중에 쿼리를 실행하더라도 특정 계좌간 이체하는 양 쪽을 볼 수 없다. 
- 성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미한다.
- 시스템 문제, DB 일관성 체크 등을 하더라도 유지되어야 함을 의미한다.
- 전형적으로 모든 트랜잭션은 로그로 남고 시스템 장애 발생 전 상태로 되돌릴 수 있다.
- 트랜잭션은 로그에 모든 것이 저장된 후에만 commit 상태로 간주될 수 있다.

 

4. 엔티티(Entity) 관계 모델

4.1 Employees 테이블과 Departments 테이블의 관계 도표 생성

=> 부서에는 0명 이상의 사원을 갖고 있다.

=> 사원은 부서를 0개 혹은 1개를 가진다.

4.2 시나리오(카디널리티)

4.3 ER 모델링의 장점

- 조직에 대한 정보를 정확하고 자세하게 문서화 => 품질보증에 사용

- 정보 요구사항의 범위를 명확히 기술

- 데이터베이스 설계를 쉽게 이해할 수 있는 표본 제공

- 복수 응용프로그램의 통합화를 위한 효과적 프레임워크 제공

 

 

5. 관계형 데이터베이스의 기본 구조

일반적 개념 모델링 DB객체
데이터 집합,
Relation,
관계집합(Relation Set)
개체집합(Entity Set) 테이블(table)
관계집합 중 어떤 행(row) 튜플(tuple), 엔티티(Entity) 레코드(record)
관계집합 중 어떤 열(column) 속성(attribute) 필드(field)

 

6. 테이블 관련 용어

행(row) 테이블에서 각 행은 중복되지 않으며 기본키에 의해 식별된다. 행의 순서는 무의미하다.
열(column) 한 종류의 데이터를 나타내며 한 열의 데이터는 같은 타입을 갖는다.
기본키(primary key) 기본키는 유일하며 null값을 가질 수 없다. 식별자라고 한다.
외래키(foreign key) 다른 테이블의 기본키 혹은 고유키를 참조하여 사용한다.
필드(field) 행과 열이 교차하는 곳을 말하고, 하나의 값만 가진다.
null 필드는 그 안에 값을 안 가질 수 있다.

 

오라클 DBMS

1. 실습 환경 구축

- https://www.oracle.com 접속

- Oracle Database Express Edition 다운로드

Oracle Database Express Edition (XE) Downloads

 

Oracle Database Express Edition (XE) Downloads

Support Oracle Database Express Edition (XE) is a community supported edition of the Oracle Database family. Please go to the Oracle Database XE Community Support Forum for help, feedback, and enhancement requests. Note: Oracle Support Services only provid

www.oracle.com

- SQLDeveloper 다운로드

Oracle SQL Developer Downloads

 

Oracle SQL Developer Downloads

This archive. will work on a 32 or 64 bit Windows OS. The bit level of the JDK you install will determine if it runs as a 32 or 64 bit application. This download does not include the required Oracle Java JDK. You will need to install it if it's not already

www.oracle.com

 

 

2. 계정 초기화 하기

SQL> conn sys /as sysdba
Enter password:
Connected.
SQL> alter session set "_ORACLE_SCRIPT"=true;
Session altered.
SQL> @?/demo/schema/human_resources/hr_main.sql
specify password for HR as parameter 1:
1의 값을 입력하십시오: hr
specify default tablespeace for HR as parameter 2:
2의 값을 입력하십시오: users
specify temporary tablespace for HR as parameter 3:
3의 값을 입력하십시오: temp
specify log path as parameter 4:
4의 값을 입력하십시오: $ORACLE_HOME/demo/schema/log/

 

3. 쿼리 실행

 

4. sample Table

728x90
반응형
LIST

'IT > SQL' 카테고리의 다른 글

[SQL] 5. 분석 함수  (0) 2023.05.11
[SQL] 4. 그룹 함수를 이용한 데이터 집계  (0) 2023.05.10
[SQL] 3. 함수 - 2  (0) 2023.05.09
[SQL] 3. 함수 - 1  (0) 2023.05.09
[SQL] 2. SELECT문  (0) 2023.05.08
728x90
반응형
SMALL
package miniprj.model;

import lombok.Data;

@Data
public class Book {
	// 예약자성함
	   String name;
	   // 체크인날짜
	   String checkIn;
	   // 체크아웃 날짜
	   String checkOut;
	   // 예약한 객실(standard, superior, suite 셋 중 하나)
	   String room;
	   // 예약 비밀번호
	   String password;
}
package miniprj.model;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

public class BookDAO implements IBookDAO{

	@Override
	public int deleteBook(String name, String password) {
		int rowCount=0;
		String sql="delete from book where cust_name=? and pwd=?";
		Connection con=null;
		try {
			con=BookDataSource.getConnection();
			PreparedStatement stmt=con.prepareStatement(sql);
			stmt.setString(1, name);
			stmt.setString(2, password);
			rowCount=stmt.executeUpdate();
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			BookDataSource.closeConnection(con);
		}
		return rowCount;
	}

	@Override
	public int insertBook(Book book) {
		int rowCount=0;
		String sql="insert into book "
				+ "(cust_name, checkin, checkout, room, pwd) values(?,?,?,?,?)";
		Connection con=null;
		try {
			con=BookDataSource.getConnection();
			PreparedStatement stmt=con.prepareStatement(sql);
			stmt.setString(1, book.getName());
			stmt.setString(2, book.getCheckIn());
			stmt.setString(3, book.getCheckOut());
			stmt.setString(4, book.getRoom());
			stmt.setString(5, book.getPassword());
			rowCount=stmt.executeUpdate();
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			BookDataSource.closeConnection(con);
		}
		return rowCount;
	}

	@Override
	public int updateBook(Book book) {
		String sql="update book set checkin=?, checkout=?, room=? "
				+ "where cust_name=? and pwd=?";
		int rowCount=0;
		Connection con=null;
		System.out.println(book);
		try {
			con=BookDataSource.getConnection();
			PreparedStatement stmt=con.prepareStatement(sql);
			stmt.setString(1, book.getCheckIn());
			stmt.setString(2, book.getCheckOut());
			stmt.setString(3, book.getRoom());
			stmt.setString(4, book.getName());
			stmt.setString(5, book.getPassword());
			rowCount=stmt.executeUpdate();
			
		} catch (Exception e) {
			throw new RuntimeException();
		}finally {
			BookDataSource.closeConnection(con);
		}

		return rowCount;
	}
	public boolean login(String name, String password) {
		String sql="select * from book where cust_name=? and pwd=?";
		int rowCount=0;
		Connection con=null;
		try {
			con=BookDataSource.getConnection();
			PreparedStatement stmt=con.prepareStatement(sql);
			stmt.setString(1, name);
			stmt.setString(2, password);
			ResultSet rs=stmt.executeQuery();
			if (rs.next()) {
				return true;
			}else{
				System.out.println("일치하는 정보가 없습니다.");
				return false;
			}
		}catch (Exception e) {
			return false;
		}
	}

	@Override
	public int getBookCount() {
		String sql="select count(*) from book";
		int rowCount=0;
		Connection con=null;
		try {
			con=BookDataSource.getConnection();
			PreparedStatement stmt=con.prepareStatement(sql);
			ResultSet rs=stmt.executeQuery();
			rs.next();
			rowCount=rs.getInt(1);
		} catch (Exception e) {
			throw new RuntimeException();
		}finally {
			BookDataSource.closeConnection(con);
		}
		return rowCount;
	}

	@Override
	public Book getOne(String name, String password) {
		String sql="select * from book where cust_name=? and pwd=?";
		Connection con=null;
		Book book=new Book();
		try {
			con=BookDataSource.getConnection();
			PreparedStatement stmt=con.prepareStatement(sql);
			stmt.setString(1, name);
			stmt.setString(2, password);

			ResultSet rs=stmt.executeQuery();
			while(rs.next()) {
				book.setName(rs.getString("cust_name"));
				book.setCheckIn(rs.getString("checkin"));
				book.setCheckOut(rs.getString("checkout"));
				book.setRoom(rs.getString("room"));
				book.setPassword(rs.getString("pwd"));
			}
		} catch (Exception e) {
			throw new RuntimeException();
		}finally {
			BookDataSource.closeConnection(con);
		}
		return book;
	}

	@Override
	public ArrayList<Book> getAllBooks() {
		// TODO Auto-generated method stub
		ArrayList<Book> list = new ArrayList<>();
		String sql = "select * from book";
		Connection con = null;
		
		try {
			con = BookDataSource.getConnection();
			PreparedStatement stmt = con.prepareStatement(sql);

			ResultSet rs = stmt.executeQuery();

			while(rs.next()) {
				Book book = new Book();
				book.setName(rs.getString("cust_name"));
				book.setRoom(rs.getString("room"));
				book.setPassword(rs.getString("pwd"));
				book.setCheckIn(rs.getString("checkin"));
				book.setCheckOut(rs.getString("checkout"));
				list.add(book);
			}
		}catch(SQLException e) {
			throw new RuntimeException(e);
		} finally {
			BookDataSource.closeConnection(con);
		}

		return list;

	}


}
package miniprj.model;

import java.sql.Connection;
import java.sql.SQLException;
import org.apache.commons.dbcp2.BasicDataSource;

public class BookDataSource {
	private static final String DRIVER = "oracle.jdbc.OracleDriver";
	private static final String URL = "jdbc:oracle:thin:@localhost:1521:xe";
	private static final String USERNAME = "hr";
	private static final String PASSWORD = "hr";
	
	private static BasicDataSource dataSource;
	
	static {
		try {
			dataSource = new BasicDataSource();
			dataSource.setDriverClassName(DRIVER);            
			dataSource.setUrl(URL);
			dataSource.setUsername(USERNAME);                                  
			dataSource.setPassword(PASSWORD);  
			dataSource.setInitialSize(10);
			dataSource.setMaxTotal(10);
			System.out.println("DataSource created");
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}
	
	public static Connection getConnection() throws SQLException {
		return dataSource.getConnection();
	}

	public static void closeConnection(Connection con) {
		if(con!=null) {
			try {
				con.close();
			}catch(Exception e) {}
		}
	}
}
package miniprj.model;

import java.util.ArrayList;

public interface IBookDAO {
	public int deleteBook(String name, String password);
	public int insertBook(Book book);
	public int updateBook(Book book);
	
	public int getBookCount();
	public Book getOne(String name, String password);
	public ArrayList<Book> getAllBooks();
}
package miniprj;

import java.util.List;
import java.util.Scanner;

import miniprj.model.Book;
import miniprj.model.BookDAO;

public class BookWin {
	static boolean isCustomer;
	   static boolean isAdmin;
	   private static  Scanner scan = new Scanner(System.in);
	   static BookDAO bookDao = new BookDAO();
	   static String name = null;
	   static String pwd = null;

	   // 호텔 예약 리스트
	   public static void list(Book list) {
	      System.out.printf("%-6s%-12s%-16s%-40s",list.getName(), list.getCheckIn(), list.getCheckOut(), list.getRoom());
	      System.out.println();
	   }

	   public static void mainMenu() {
	      System.out.println();
	      System.out.println("--------------------------------------------------------");
	      System.out.println("메인메뉴: 1.예약 | 2.조회 | 3.수정 | 4.삭제 | 5.로그아웃 | 6.종료");
	      System.out.println("메뉴선택: ");
	      String menuNo = scan.nextLine();
	      System.out.println();

	      switch(menuNo) {
	      case "1" -> {
	         Book book = new Book();

	         System.out.print("예약자: ");
	         book.setName(scan.nextLine());
	         System.out.print("체크인 날짜: ");
	         book.setCheckIn(scan.nextLine());
	         System.out.print("체크아웃 날짜: ");
	         book.setCheckOut(scan.nextLine());
	         System.out.print("객실: ");
	         book.setRoom(scan.nextLine());
	         System.out.println("비밀번호: ");
	         book.setPassword(scan.nextLine());

	         bookDao.insertBook(book);
	         break;
	      }

	      case "2" -> {
	         System.out.println("[호텔 예약관리 시스템]");
	         System.out.println("--------------------------------------------------------");
	         System.out.printf("%-6s%-12s%-16s%-40s", "성함","체크인 날짜","체크아웃 날짜","객실");
	         System.out.println("--------------------------------------------------------");
	         if (isAdmin) {
	            List<Book> list = bookDao.getAllBooks();
//	            System.out.println(list);
	            for(int i=0;i<list.size();i++) {
	               list(list.get(i));
	            }
	         } else if(isCustomer) {
	            Book book = bookDao.getOne(name, pwd);
	            list(book);
	         }
	         break;
	      }

	      case "3" -> {
	         Book book = bookDao.getOne(name, pwd);

	         System.out.print("체크인 날짜: ");
	         book.setCheckIn(scan.nextLine());
	         System.out.print("체크아웃 날짜: ");
	         book.setCheckOut(scan.nextLine());
	         System.out.print("객실: ");
	         book.setRoom(scan.nextLine());

	         bookDao.updateBook(book);
	         break;

	      }
	      case "4" -> {
	         Book onesBook = bookDao.getOne(name, pwd);
	         if(!onesBook.getName().equals(name)) {
	            System.out.println("예약건이 없습니다.");
	            break;
	         } 

	         int rowCount = bookDao.deleteBook(name, pwd);
	         System.out.println(rowCount + "건의 에약이 취소되었습니다.");
	         break;
	      }
	      case "5" -> {
	         isAdmin = false;
	         isCustomer = false;
	         name = null;
	         pwd = null;
	         loginMenu();
	         break;
	      }
	      case "6" -> {
	         System.out.println("프로그램이 종료되었습니다.");
	         System.exit(0);
	      }
	      }
	   }

	   public static boolean loginMenu() {
	      System.out.println();
	      System.out.println("--------------------------------------------------------");
	      System.out.println("성함을 입력하세요: ");
	      name = scan.nextLine();
	      System.out.println("비밀번호를 입력하세요: ");
	      pwd = scan.nextLine();

	      if(name.equals("admin") && pwd.equals("admin")) {
	         isAdmin = true;
	         return true;
	      } else if(bookDao.login(name, pwd)){
	         isCustomer = true;
	         mainMenu();
	         return true;
	      } else {

	         System.out.println("회원정보가 일치하지 않습니다.");
	         return false;
	      }


	   }

	   public static void main(String[] args) {
	      while(true) {
	         if(loginMenu()) {
	        	 while(isAdmin || isCustomer) {
	        		 mainMenu();
	        	 }
	            
	         }

	      }
	   }

}
728x90
반응형
LIST

'IT > JAVA' 카테고리의 다른 글

[JAVA] #19 데이터베이스 입출력(게시판 프로그램)  (1) 2023.05.02
[JAVA] #18 입출력 스트림  (0) 2023.05.01
[JAVA] #17 스트림 요소 처리  (0) 2023.05.01
[JAVA] #16 람다식  (0) 2023.04.27
[JAVA] #15 컬렉션 자료구조  (0) 2023.04.27
728x90
반응형
SMALL
package ch20.oracle.sec12;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;


public class BoardExample {
	//매개변수
	private static Scanner scanner = new Scanner(System.in);
	private static Connection con=null;
	private static final String url="jdbc:oracle:thin:@localhost:1521:xe";
	
	
   	//게시물 목록 출력
	public static void list() {
		System.out.println();
		System.out.println("[게시물 목록]");
		System.out.println("--------------------------------------------------");
		System.out.printf("%-6s%-12s%-16s%-40s\n","no","writer","date","title");
		System.out.println("--------------------------------------------------");
		
		try {
			String sql="select * from boards order by bno desc";
			PreparedStatement pstmt=con.prepareStatement(sql);
			ResultSet rs=pstmt.executeQuery();
			
			while(rs.next()) {
				Board board = new Board();
				board.setBno(rs.getInt("bno"));
				board.setBtitle(rs.getString("btitle"));
				board.setBcontent(rs.getString("bcontent"));
				board.setBwriter(rs.getString("bwriter"));
				board.setBDate(rs.getDate("bdate"));
				System.out.printf("%-6s%-12s%-16s%-40s\n", 
						board.getBno(), board.getBwriter(),board.getBDate(),board.getBtitle());
			}
			rs.close();
			pstmt.close();
		} catch (SQLException e) {
			e.printStackTrace();
			exit();
		}
        //메뉴 부르기
		mainMenu();
	}
	
    //메뉴
	public static void mainMenu() {
		System.out.println();
		System.out.println("--------------------------------------------------");
		System.out.println("메인 메뉴 : 1.Create | 2.Read | 3.Clear | 4.Exit");
		System.out.print("메뉴 선택: ");
		int menu = scanner.nextInt();
		scanner.nextLine();
		switch (menu) {
		case 1 -> create();
		case 2 -> read();
		case 3 -> clear();
		case 4 -> exit();
		default -> System.out.println("메뉴를 잘못 입력함.");
		}
	}
	
    //1번 create
    //데이터 생성 insert
	private static void create() {
		Board board = new Board();
		System.out.println("[새 게시물 입력]");
		System.out.print("제목: ");
		board.setBtitle(scanner.nextLine());
		System.out.print("내용: ");
		board.setBcontent(scanner.nextLine());
		System.out.print("작성자: ");
		board.setBwriter(scanner.nextLine());
		
		System.out.println("--------------------------------------------------");
		System.out.println("보조 메뉴: 1.OK | 2.Cancel");
		System.out.print("메뉴 선택: ");
		int menu=scanner.nextInt();

		if(menu==1) {
			try {
				String sql="insert into boards (bno, btitle, bcontent, bwriter, bdate)"
						+ " values(SEQ_BNO.NEXTVAL,?,?,?,sysdate)";
				PreparedStatement pstmt = con.prepareStatement(sql);
				pstmt.setString(1, board.getBtitle());
				pstmt.setString(2, board.getBcontent());
				pstmt.setString(3, board.getBwriter());
				pstmt.executeUpdate();
				pstmt.close();
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
				exit();
			}
		}
		list();
	}
	
    //2번 read
    //데이터 가져오기 select    
	private static void read() {
		System.out.println("[게시물 읽기");
		System.out.print("bno: ");
		int no=scanner.nextInt();
		scanner.nextLine();
		try {
			String sql="select * from boards where bno = ?";
			PreparedStatement stmt=con.prepareStatement(sql);
			stmt.setInt(1, no);
			ResultSet rs=stmt.executeQuery();
			if(rs.next()) {
				Board board = new Board();
				board.setBno(rs.getInt("bno"));
				board.setBtitle(rs.getString("btitle"));
				board.setBcontent(rs.getString("bcontent"));
				board.setBwriter(rs.getString("bwriter"));
				board.setBDate(rs.getDate("bdate"));
				System.out.println("#############");
				System.out.println("번호: "+board.getBno());
				System.out.println("제목: "+board.getBtitle());
				System.out.println("내용: "+board.getBcontent());
				System.out.println("작성자: "+board.getBwriter());
				System.out.println("날짜: "+board.getBDate());
			
				System.out.println("--------------------------------------------------");
				System.out.println("보조 메뉴: 1.Update | 2.Delete | 3.List");
				System.out.print("메뉴 선택: ");
				int menu=scanner.nextInt();
				scanner.nextLine();

				if(menu==1) {
					update(board);
				}else if(menu==2) {
					delete(board);
				}
			}
			rs.close();
			stmt.close();
		} catch (Exception e) {
			e.printStackTrace();
			exit();
		}
		
		list();
	}
	
    //2-1번 update
    //데이터 수정 update
	public static void update(Board board) {
		System.out.println("[수정 내용 입력]");
		System.out.print("제목: ");
		board.setBtitle(scanner.nextLine());
		System.out.print("내용: ");
		board.setBcontent(scanner.nextLine());
		System.out.print("작성자: ");
		board.setBwriter(scanner.nextLine());
		
		System.out.println("--------------------------------------------------");
		System.out.println("보조 메뉴: 1.OK | 2.Cancel");
		System.out.print("메뉴 선택: ");
		int menu=scanner.nextInt();
		
		if(menu==1) {
			try {
				String sql="update boards set btitle=?, bcontent=?, bwriter=? where bno=?";
				PreparedStatement stmt=con.prepareStatement(sql);
				stmt.setString(1, board.getBtitle());
				stmt.setString(2, board.getBcontent());
				stmt.setString(3, board.getBwriter());
				stmt.setInt(4, board.getBno());
				stmt.executeUpdate();
				stmt.close();
			} catch (Exception e) {
				e.printStackTrace();
				exit();
			}
		}
		list();
	}
    
    //2-2번 delete
    //데이터 삭제 delete
	public static void delete(Board board) {
		try {
			String sql="delete from boards where bno=?";
			PreparedStatement stmt=con.prepareStatement(sql);
			stmt.setInt(1, board.getBno());
			stmt.executeUpdate();
			stmt.close();
		} catch (Exception e) {
			e.printStackTrace();
			exit();
		}
		list();
		
	}
	
    //3번 clear
    //데이터 모두 삭제 truncate
	private static void clear() {
		System.out.println("[게시물 전체 삭제]");
		System.out.println("--------------------------------------------------");
		System.out.println("보조 메뉴: 1.Ok | 2.Cancel");
		System.out.print("메뉴 선택: ");
		int menu=scanner.nextInt();
		scanner.nextLine();
		if(menu==1) {
			try {
				String sql="truncate table boards";
				PreparedStatement stmt=con.prepareStatement(sql);
				stmt.executeUpdate();
				stmt.close();
			} catch (Exception e) {
				e.printStackTrace();
				exit();
			}
		}
		list();
	}
    
    //4번 exit
	private static void exit() {
		if(con!=null) {
			try {
				con.close();
			} catch (SQLException e) {
				// TODO: handle exception
			}
		}
		System.out.println("***게시판 종료***");
		System.exit(0);
	}
    
    //main
	public static void main(String[] args) {
		try {
			Class.forName("oracle.jdbc.OracleDriver");
			con = DriverManager.getConnection(url,"hr","hr");
			
		} catch (Exception e) {
			e.printStackTrace();
			exit();
		} finally {
			list();
		}
		
		
	}
}
728x90
반응형
LIST

'IT > JAVA' 카테고리의 다른 글

[JAVA] 호텔 예약 관리 프로그램  (0) 2023.05.08
[JAVA] #18 입출력 스트림  (0) 2023.05.01
[JAVA] #17 스트림 요소 처리  (0) 2023.05.01
[JAVA] #16 람다식  (0) 2023.04.27
[JAVA] #15 컬렉션 자료구조  (0) 2023.04.27

+ Recent posts