일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 그래프 생성 문법
- Sum
- 빅데이터분석
- count
- sql
- 여러 데이터 검색
- 정보획득량
- if문 작성법
- max
- 빅데이터
- 데이터분석가
- 순위출력
- loop 문
- sqld
- 총과 카드만들기
- 회귀분석
- 회귀분석 알고리즘
- 데이터분석
- 막대그래프
- difftime
- 단순회귀 분석
- merge
- 히스토그램 그리기
- 그래프시각화
- %in%
- 팀스파르타
- 상관관계
- 불순도제거
- Dense_Rank
- Intersect
- Today
- Total
ch0nny_log
[빅데이터분석] SQL_TIL 19(with절,SUBQUERY FACTORING, 유저생성,데이터 추출) 본문
[빅데이터분석] SQL_TIL 19(with절,SUBQUERY FACTORING, 유저생성,데이터 추출)
chonny 2024. 6. 10. 17:12★ 점심시간문제:
우리반 테이블에 나이 컬럼에 체크 제약을 거시오. 나이가 20~ 40 까지의 데이터만 입력 또는 수정되겠금 체크 제약을 거시오. 제약을 걸고 자신의 나이를 41로 업데이트를 해서 안되는 화면을 검사 받으시면 됩니다.
|
alter table emp19
add constraint emp19_age_ck check(age between 20 and 40);
update emp19
set age =41;
[TIL 19] 240610
[복습] 제약을 거는 방법 2가지
1. 테이블 생성 시 제약을 거는 방법
2. 만들어진 테이블에 제약을 거는 방법
1) 저장된 파일 demo를 cmd로 열기
sqlplus c##scott/tiger
@demo.sql
문제 1.1. dept 테이블의 deptno에 primary key 제약을 거시오
alter table dept add constraint dept_deptno_pk primary key(deptno);
문제 1.2. emp 테이블의 deptno에 foreign key 제약을 걸면서 deptno테이블에 deptno를 참조해라고 하시오.alter table emp add constraint emp_deptno_fk foreign key(deptno) references dept(deptno);
문제 1.3. dept 테이블에 부서번호 10번과 40번을 지우시오.
delete from dept where deptno =10; ## 10번은 무결성 제약조건이 위배되어 지워지지 않음 delete from dept where deptno =40; ## 40번은 emp에 자식테이블이 없어 지워짐
문제 1.4. emp테이블에 deptno가 70번인 사원의 데이터를 입력하시오.
insert into emp(empno, ename, sal, deptno) values( 9392, 'JACK', 4000, 70);
※ 현업에서 위와 같이 부모자식관계의 테이블을 구성하는 이유?
-> outer join을 사용하지 않아도 equi join으로 제대로 조인된 결과를 볼 수 있게 해 주기 때문.
-> 엉뚱한 부서버노가 emp테이블에 있으면 어쩔 수 없이 outer join을 써야 됨. (대용량 데이터 베이스 환경에서는 outer join의 검색성능이 좋지 않고 데이터 분석 시에도 빠른 분석을 하기가 어려움_ 데이터 품 질의 위해 부모자식 관계를 현성해 주는 게 바람직함)
문제 1.5. dept 테이블의 primary key 제약을 삭제하시오.alter table dept drop constraint dept_deptno_pk;
설명: emp테이블에 deptno가 dept테이블의 deptno를 참조하고 있기 때문에 제약이 drop이 안됨. drop 하려면 cascade 옵션을 사용해야 함
alter table dept drop constraint dept_deptno_pk cascade;
설명: 이렇게 삭제하면 자식키(foreign key)와 같이 삭제됨.
* 제약조건 확인 select * from user_constraints where table_name in ('EMP','DEPT');
문제 2.1. DEPT900 테이블을 생성하는데 DEPTNO에 PRIMARY KEY 제약을 걸어서 생성하시오!
1. 테이블 레벨 문법
create table dept900 (deptno number(10), dname varchar2(10), loc varchar2(10), constraint dept900_deptno_pk primary key(deptno));
2. 칼럼 레벨 문법_ 컬럼 바로 옆에 작
create table dept900 (deptno number(10) constraint dept900_deptno_pk primary key, dname varchar2(10), loc varchar2(10));
문제 3.1. subquery를 사용한 insert를 이용해서 dept 테이블의 모든 데이터를 dept900 테이블에 입력하시오.
insert into dept900 (deptno, dname, loc) select deptno, dname, loc from dept;
문제 3.2. emp900 테이블을 생성하는데 deptno에 foreign key 제약을 걸면서 dept900 테이블에 deptno를 참고하게끔 생성하시오.
1. 테이블레벨 문법 create table emp900 (empno number(10), ename varchar2(10), sal number(10), deptno number(10), constraint emp900_dept_fk foreign key(deptno) references dept900(deptno)); 2. 컬럼레벨 문법 create table emp900 (empno number(10), ename varchar2(10), sal number(10), deptno number(10)constraint emp900_dept_fk foreign key(deptno) references dept900);
문제 3.3.emp 테이블의 empno, ename, sal, deptno를 emp900에 입력하시오. 서브쿼리를 사용한 insert 문을 이용하세요!
insert into emp900(empno, ename, sal, deptno ) select empno, ename, sal, deptno from emp;
문제 3.4. dept900 테이블에 부서번호 20번을 delete 하시오.
delete from dept900 where deptno =20;
설명: emp 테이블에 deptno가 20번 있기 때문에 지워지지 않음
문제 4. 다음의 테이블과 제약구성을 하시오.
1) dept800 (부모테이블 생성) create table dept800 (deptno number(10) constraint dept800_deptno_pk primary key, dname varchar2(10), loc varchar2(10)); 2) emp800 (자식테이블 생성) create table emp800 (empno number(10), ename varchar2(10), sal number(10), job varchar2(10), deptno number(10) constraint emp800_deptno_fk references dept800(deptno)); 3) 데이터 삽입 (부모테이블부터!!) insert into dept800 (deptno,dname, loc) select deptno,dname, loc from dept; insert into emp800 (empno, ename, sal, job, deptno) select empno, ename, sal, job, deptno from emp;
109. WITH~AS
예제 109. WITH 절 사용하기 1(WITH~AS)
WITH절을 사용하는 이유?
-> FROM 절의 서브쿼리처럼 데이터 쿼리문을 select 해온 결과 데이터를 가지고 연산을 하거나 조건읠 줘서 출력하고 싶을 때 유용한 sql문
그런데 from 절의 서브쿼리와 차이점은 from 절의 서브쿼리는 데이터를 메모리에 저장하는데 with 절은 디스크에 저장함 (데이터를 임시 테이블오 저장하고 있다는 게 차이)
Q1. 이름, 월급, 월급의 순위를 출력하시오.
select ename, sal , dense_rank()over(order by sal desc) as 순위 from emp;
Q2. from 절의 서브쿼리를 이용하여 이름과 월급, 월급의 순위를 출력하는데 순위가 1,3,5등만 출력되게 하시오.
설명: from 절의 서브쿼리로 가져오는 데이터를 메모리에 올리는 SQL인데 오라클 프로세서 하나가 사용할 수 있는 메모리가 몇 십메가 ~ 몇백메가 밖에 안됩니다. 그런데 위의 FROM 절 서브쿼리 안에 이름, 월급, 순위를 가져오는 데이터가 굉장히 많다면 메모리에 다 올릴 수 가 없습니다. 그러면 메모리 부족 오류가 발생하면서 위의 SQL이 오류가 납니다.select ename, sal , 순위 from (select ename, sal , dense_rank()over(order by sal desc) as 순위 from emp) where 순위 in (1,3,5);
-> 이럴때 with 절을 쓰면 됨!!
with emp_rank as (select ename, sal , dense_rank()over(order by sal desc) as 순위 from emp ) select ename, sal, 순위 from emp_rank;
Q3. 위의 WITH절에서 사용하고 있는 임시 테이블이 정말 만들어졌는지 확인하시오.
설명: 위의 실행계획은 오라클 옵티마이져가 with절을 from 절의 서브쿼리로 SQL문장으로 변경해서 수행한것 입니다. 그래서 WITH 절의 효과를 못본겁니다. WITH 절의 효과는 작은 메모리 영역을 서로 사용하겠다고 경합을 일으키지 않아도 되고 넉넉한 디스크를 사용하는것입니다. 경합을 일으키면 SQL 이 느려집니다. 그래서 임시 테이블 스페이스를 사용하겠금 오라클 힌트를 써야합니다.explain plan for with emp_rank as (select ename, sal , dense_rank()over(order by sal desc) as 순위 from emp ) select ename, sal, 순위 from emp_rank; select * from table(dbms_xplan.display);
** with 절 사용할때 유용한 힌트 2가지
1. /*+ materializw */ 힌트: 임시테이블 스페이스에 임시 테이블을 생성해라
2. /*+ inlune */ 힌트: 임시테이블 만들이 말고 from절의 서브쿼리처럼 수행해 메모리에 데이터에 올려라.
explain plan for with emp_rank as ( select /*+ materialize */ ename, sal, dense_rank() over ( order by sal desc ) 순위 from emp ) select ename, sal, 순위 from emp_rank where 순위 in ( 1, 3, 5 ); select * from table(dbms_xplan.display);
Q4. 아래의 WITH절에 INLINE 힌트를 이용해서 임시 테이블을 만들지 말고 수행되게 하시오
explain plan for with emp_rank as ( select /*+ INLINE */ ename, sal, dense_rank() over ( order by sal desc ) 순위 from emp ) select ename, sal, 순위 from emp_rank where 순위 in ( 1, 3, 5 ); select * from table(dbms_xplan.display);
문제 1. 아래 sql을 with절로 변경하시오
1) 튜닝전 select ename, sal, round(부서평균) from (select ename, sal , avg(sal) over(partition by deptno) 부서평균 from emp ) where sal > 부서평균; 2) 튜닝 후 with emp_avg as ( select ename, sal , avg(sal) over(partition by deptno) 부서평균 from emp ) select ename, sal, round(부서평균) from emp_avg where sal > 부서평균;
설명: 힌트를 사용하는 이유는 아직 오라클 옵티마이져가 사람이 손길이 많이 필요한 아주 미숙한 상태임.
문제 2. 아래 sql을 with절로 변경하시오
1) 튜닝전 select ename,loc, sal, 순위 from (Select e.ename, d.loc, e.sal , dense_rank()over(partition by loc order by sal desc) 순위 from emp e, dept d where e.deptno= d.deptno) where 순위 =1; 2) 튜닝후 with ed_sal as (Select e.ename, d.loc, e.sal , dense_rank()over(partition by loc order by sal desc) 순위 from emp e, dept d where e.deptno= d.deptno) select ename, loc, sal, 순위 from ed_sal where 순위 =1;
문제 3.1. 직업과 직업별 토털월급을 출력하시오.
select job, sum(sal) from emp group by job;
문제 3.2. 위의 결과에서 직업별 토털월급들만 출력하시오.
select sum(sal) from emp group by job;
문제 3.3 위의 결괏값의 평균값을 출력하시오.select avg(sum(sal)) from emp group by job;
※ group 합수 특징
1. 그룹함수는 중첩을 할 수 있습니다.
2. 그룹함수는 null값을 무시합니다.
문제 3.4. 직업과 직업별 토털월급을 출력하는데 직업별 토털월급이 직별 토털월급들에 대한 평균값보다 더 큰 것만 출력하시오.select job, sum(sal) from emp group by job having sum(sal)> (select avg(sum(sal)) from emp group by job);
설명: 직업이 아주 많아서 직업을 grouping 하는데 시간이 20분이 걸린다고 해보면 메인쿼리 20분, 서브쿼리 20분 걸려서 총 40분이 걸리는 SQL이라고 가정합니다.
문제 3.5. 위 sql을 with 절로 변경하시오.select job, 토탈 from job_sumsal where 토탈>(select avg(토탈) from job_sumsal);
문제 3.6. 위의 SQL을 WITH 절로 변경하시오 !with job_sumsal as (select job,sum(sal) as 토탈 from emp group by job) select job, 토탈 from job_sumsal where 토탈>(select avg(토탈) from job_sumsal);
설명: 이 sql은 직업별 토털월급을 구하는 임시테이블을 구성할 때만 20분 걸리고 더 이상 오래 걸리지 않음.
문제 4. 통신사, 통신사별 토탈 나이를 출력하는데 토탈나이의 평균값보다 더 큰 것만 출력하시오.
1) 튜닝전 select lower(telecom), sum(age) from emp19 group by lower(telecom) having sum(age) >(select avg(sum(age)) from emp19 group by lower(telecom)); 2) 튜닝후 with telecom_sumage as ( select lower(telecom)as 통신사, sum(age) as 토탈 from emp19 group by lower(telecom)) select 통신사, 토탈 from telecom_sumage where 토탈 > (select avg(토탈) from telecom_sumage);
※ with절을 사용 했을 때의 장점
- 일부러 테이블& view를 생성하지 않아도
★★ 문제5. 숫자 1-10까지의 토탈값, 평균값, 최대값, 최소값을 출력하시오.
with number_ten as(select level as num from dual connect by level <=10) select sum(num),avg(num),max(num), min(num) from number_ten;
문제 6. 1~10까지의 숫자중에서 짝수만 출력하시오
select num from number_even where mod(num,2)=0;
문제 7. 1-10까지의 숫자중에서 홀수 숫자의 합을 출력하시오.
with number_sum as(select level as num from dual connect by level <=10) select sum(num) from number_sum where mod(num,2)=1;
문제 8. 직업과 직업별 토탈월급에 대하여 평균값, 분산값, 표준편차값을 출력하시오.
with job_sumsal as(select job, sum(sal) as 토탈 from emp group by job) select avg(토탈), var_pop(토탈), stddev(토탈) from job_sumsal;
1) 분산값 ? 데이터의 퍼짐 정도
데이터값들이 평균으로 부터 얼마나 떨어져있는지를 나타내는 척도
평균에 몰려있는지 아니면 평균에서 멀어져 있는지를 나타내는 척도
- var_pop: 모집단의 분산을 계산하는 함수
- var_samp: 표본의 분산을 계산하는 함수
2) 표준편차? 분산값에 루트를 씌운값(제곱근)
데이터값들이 평균으로 부터 얼마나 떨어져 있는지 나타내는 값
110. SUBQUERY FACTORING
select deptno, 부서토탈 from( select job, sum(sal) as 직업토탈 from emp group by job) as job_sumsal, ( select deptno, sum(sal) as 부서토탈 from emp group by deptno having sum(sal) > (select avg(직업토탈) + 3000 from job_sumsal)) as dept_sumsal;
Q2. 위의 결과를 WITH 절로 구현하시오.
: with 절에는 여러 문장 사용가능with job_sumsal as(select job, sum(sal) 직업토탈 from emp group by job), deptno_sumsal as(select deptno, sum(sal) 부서토탈 from emp group by deptno having sum(sal) > (select avg(직업토탈) +3000 from job_sumsal) ) select deptno,부서토탈 from deptno_sumsal;
※ 현업 tip
Q. 임시 테이블을 다음과 같이 2개로 해서 WITH 절을 작성하시오 !
튜닝 요청 받은 SQL의 이전 작성 SQL을 찾아서 두개의 차이점을 비교합니다. (TOAD, ORANGE 프로그램 이용)
그래서 변경된 부분만 튜닝하면 됨. 변경된 부분이 어느 임시테이블을 만드는 쿼리문 1개인데 그짧은 SQL만 튜닝하면 됨. 예제 111. WITH 절 사용하기 2(SUBQUERY FACTORING)
: 기존의 서브쿼리문으로는 구현하지 못하는 기능을 WITH절로 구현하기 위한 기능with man_info as ( select ename, gender, age from emp19 where gender='남' ), woman_info as ( select ename, gender, age from emp19 where gender='여' ) select gender, round(avg(age)) from man_info group by gender union all select gender, round(avg(age)) from woman_info group by gender;
문제 1. 아래의 SQL을 WITH 절로 변경하시오.
1) 튜닝전 select lower(telecom), max(age), min(age), round(avg(age)) from emp19 where lower(telecom)='sk' group by lower(telecom) union all select lower(telecom), max(age), min(age), round(avg(age)) from emp19 where lower(telecom)='lg' group by lower(telecom) union all select lower(telecom), max(age), min(age), round(avg(age)) from emp19 where lower(telecom)='kt' group by lower(telecom); 2) 튜닝 후 with sk_telecom as ( select lower(telecom) 통신사, age from emp19 where lower(telecom)='sk' ), lg_telecom as ( select lower(telecom) 통신사, age from emp19 where lower(telecom)='lg' ), kt_telecom as ( select lower(telecom) 통신사, age from emp19 where lower(telecom)='kt' ) select 통신사, max(age), min(age), round(avg(age) ) from sk_telecom group by 통신사 union all select 통신사, max(age), min(age), round(avg(age) ) from lg_telecom group by 통신사 union all select 통신사, max(age), min(age), round(avg(age) ) from kt_telecom group by 통신사;
111. 유저생성하기
예제 111. 유저 생성하기
Q1. C##KING 이라는 유저의 패스워드를 TIGER로 해서 생성하시오.
create user c##king identified by tiger;
설명: c##을 앞에 붙여서 유저를 만드는 이유가 컨테이너 데이터 베이스의 공용유저를 만들 때는 c##을 앞에 붙여야됨.
Q2. C##을 안붙이고 유저를 생성하시오.명령 프롬프트창을 열고 sys 유져로 접속을 합니다. sys 유져는 오라클의 최고 권한자 입니다. # 1. 오라클 최고 권한자로 접속을 합니다. C:\Users\ITWILL>sqlplus sys/oracle_4U as sysdba
#2. 유져를 생성할 때 유져이름 앞에 필수로 접두어로 붙여줘야하는 키워드를 확인 SQL> show parameter common_user_prefix #3. c## 을 안붙여도 되겠금 null 로 common_user_prefix 를 셋팅함 SQL> alter system set common_user_prefix= '' scope=spfile; #4. db를 내렸다 올립니다. SQL> shutdown immediate SQL> startup
#5. c## 없이 king 유져를 생성합니다. SQL> create user king identified by tiger; #6. connect 와 resource 권한을 king 에게 부여합니다. SQL> grant connect, resource to king; 설명: king 에게 connect (db에 접속할 수 있는 권한 ) 을 주고 resource(테이블 생성과 같은 기본적인 권한) 을 줍니다. #7. king 으로 접속해봅니다. SQL> connect king/tiger 연결되었습니다. SQL> show user
문제 1. sys 유져에서 smith 라는 유져를 생성하는데 패스워드를 oracle1234 로 해서 생성하고 connect 와 resource 권한을 부여하시오 !
SQL> connect sys/oracle_4U as sysdba 연결되었습니다. 문제687. sys 유져에서 smith 라는 유져를 생성하는데 패스워드를 oracle1234 로 해서 생성하고 connect 와 resource 권한을 부여하시오 ! SQL> create user smith identified by oracle1234; 사용자가 생성되었습니다. SQL> grant connect, resource to smith; 권한이 부여되었습니다.
문제 2. sqldeveloper 로 smith 유져로 접속해보시오
** 만약 권한이없다는 오류가 뜨면 명령프롬프트에 권한부여
grant dba to smith;
문제 3. sqldeveloper을 끄고 명령 프롬프트창의 sys 유저에서 smith 유저를 drop 하시오.
SQL> show user USER은 "SYS"입니다 SQL> drop user smith cascade; 사용자가 삭제되었습니다.
문제 4. 다시 sys 유저에서 smith 유저를 패스워드 oracle 1234 로 생성하고 dba권한을 부여하시오.
SQL> create user smith 2 identified by oracle1234; 사용자가 생성되었습니다. SQL> grant dba to smith; 권한이 부여되었습니다.
문제 5. smith 유저의 패스워드를 tiger로 변경하시오.
SQL> alter user smith 2 identified by tiger; 사용자가 변경되었습니다.
설명: 패스워드를 잃어버리면 변경하여 알아
문제 6. smith2라는 유저를 password: tiger 로 해서 생성하고 dba 권한을 부여하시오.
SQL> create user smith2 2 identified by tiger; 사용자가 생성되었습니다. SQL> grant dba to smith2; 권한이 부여되었습니다.
문제 7. c##scott 유저가 가지고 있는 모든 테이블, 인덱스, 스퀀스, 뷰를 모두다 export 하시오
C:\Users\itwill>exp c##scott/tiger file=scott.dmp owner=c##scott
문제 8. c##scott 유저의 덤프파일을 smith 유저에 임포트하시오. (cmd 에다가)
C:\Users\itwill> imp smith/tiger file=scott.dmp fromuser=c##scott touser=smith
문제 9. king 7이라는 유저를 생성하고 dba권한을 부여하고 나서 c##scott유저가 가지고 있는 모든테이블들을 king7 유저에게 임폴트하시오 . 그 후 다음 select 문 결과를 캡쳐해서 올리세요.
select count(*) from user_tables;
1) cmd에서 sql 접속하기C:\Users\ITWILL>sqlplus sys/oracle_4U as sysdba
2) 유저생성하기 후 권한 부여하기SQL> create user smith2 2 identified by tiger; 사용자가 생성되었습니다. SQL> grant dba to smith2; 권한이 부여되었습니다.
3) 기존 데이터 추출하기exp c##scott/tiger file=scott.dmp owner=c##scott
4) 새로운 유저에게 데이터 임포트하기imp king7/tiger file=scott.dmp fromuser=c##scott touser=king7
5) sqldeveloper에 테이블 접속후 테이블갯수 확인하기select count(*) from user_tables;