레이블이 함수인 게시물을 표시합니다. 모든 게시물 표시
레이블이 함수인 게시물을 표시합니다. 모든 게시물 표시

2015년 10월 30일 금요일

151007 - SubQuery 서브쿼리

***subQuery
1. 다른 query문에 포함된 query문에 포함된 query
2. 반드시 ()를 사용
3. 연산자의 오른쪽에 와야한다.
4. order by 사용금지
5. 종류
      (1) General Subquery
      (2) Relation Subquery
      
6. 유형
      (1) 단일행
      (2) 다중행
      (3) 다중열
            
7. 연산자 
      (1) 단일열
         =, >, <, >=, <=, <>....
      (2) 다중행
         in, any, all, exists, not
         
안에 있는 서브쿼리가 먼저 실행 밖에 있는 쿼리가 나중에 실행된다,
쿼리를 구별할 수 있는 방법 서브쿼리만 실행될 때 Relation Subquery

다중열
위치와 순서 같아야한다.
*MILLER의 데이터 수정
select sal, comm from emp where ename='MILLER';
update emp set sal=1500, comm=300 where ename='MILLER';


=====================================================================================
실습

1. SCOTT 의 급여보다 더 많이 받는 직원의 이름, 업무, 급여 를 조회

SELECT sal FROM emp WHERE ename = 'SCOTT' ; --3000

SELECT ename, job, sal FROM emp WHERE sal>3000;

SELECT ename, job sal FROM emp WHERE sal>(SELECT sal FROM emp WHERE ename='SCOTT');


2. 사번이 7521의 업무와 같고, 급여가 7934 보다 많은 직원의 사번, 이름, 업무, 급여를 조회

SELECT job FROM emp WHERE empno=7521;  //SALESMAN
SELECT sal FROM emp WHERE empno=7934;  //1300
select empno, ename, job, sal, from emp where job='SALESMAN' and sal>1300;

select empno, ename, job, sal, from emp where job=(select job from emp where empno=7521;) and sal>(select sal from emp where empno=7934);


3. 업무별로 최소급여를 받는 직원의 사번, 이름, 급여, 부서번호 조회

select empno, ename, sal, deptno from emp where sal in(select min(sal) from emp group by job)

select empno, ename, sal, deptno from emp where sal=800 OR sal=1250 OR sal=5000 OR sal=2450 OR sal=3000;
select min(sal) from emp group by job;

select empno, ename, sal, deptno from emp where sal in(select min(sal) from emp group by job);


4. 업무별로 최소급여보다 많은 급여를 받는 직원의 사번, 이름, 업무, 부서번호를 조회

select empno, ename, job,  sal, deptno from emp where sal > any(select min(sal) from emp group by job);
select min(sal) from emp group by job;


5. 업무별로 최대급여를 받는 직원의 사번, 이름, 업무, 부서번호를 조회

select max(sal) from emp group by job;
select empno, ename, deptno from emp where sal >= all(select max(sal) from emp group by job);


6.급여와 보너스가 30번 부서에 있는 직원의 급여와 보너스가 같은 직원에 대해 사번, 이름,., 부서번호, 급여, 보너스 조회

select empno, ename, deptno, sal, comm from emp where (sal, comm) in(select  sal, comm from emp where deptno=30);
select  sal, from emp where deptno=30 ;
select comm from emp where deptno=30;


7. 상관 서브 쿼리

*적어도 한명의 직원으로부터 보고를 받을 수 있는 직원의 이름, 업무, 입사일자, 급여를 조회

select ename, job, hiredate, sal from emp where empno in(select distinct mgr from emp) order by ename;

select ename, job, hiredate, sal from emp e where empno exists(select distinct mgr from emp where e.empno=mgr) order by ename;
select distinct mgr from emp;

151006 DB 함수 연습과제

1 이름의 첫 글자가 k 보다 크고 y 보다 작은 직원의 이름, 부서, 업무를 조회 / 단 이름순으로 정렬
SELECT ename, deptno, job from emp where ename >'K%' and ename<'Y%' order by ename;

2. 오늘부터 12월 25일 까지 몇일 남았는가
select sysdate - To_Date('2015/12/25') from dual;

3. 모든 직원이 현재까지 근무한 근무 일수를 몇주 몇일로 출력하시오. / 단 근무일수가 많은 사람순으로 조회
select ename, hiredate, trunc((sysdate-hiredate)/7)weeks, round (mod((sysdate-hiredate),7),0) days from emp order by sysdate - hiredate desc;

4. 10번 부서 직원들에 한해서 현재까지의 근무개월수를 조회하시오.
select ename, hiredate, sysdate,trunc(months_between(sysdate,hiredate),0)  from emp where deptno =10 order by months_between(sysdate,hiredate)desc;

5. 20번 부서 직원들에 한해서 입사일자로 부터 5개월이 지난 후의 날짜를 조회
select ename, deptno, add_months(hiredate,5) from emp;

6. 모든 직원에 대해 입사한 달의 근무일수를 조회
select empno, ename, hiredate, last_day(hiredate)-hiredate from emp order by last_day(hiredate)-hiredate desc;

7. 현재 급여에 15%가 증가된 급여를 계산하여 사번, 이름, 업무, 급여, 증가된급여 를 조회
select empno, ename, job, sal, sal*1.15 from emp;

8.이름, 입사일, 입사일로부터 현재까지의 근무개월수, 급여, 급여총계를 조회
select ename, hiredate, sysdate,trunc(months_between(sysdate,hiredate)) TMonths, sal, sal*trunc(months_between(sysdate,hiredate)) Tsal from emp ;
9, 업무가 analyst 면 급여를 10% 증가시키고, clerk 면 15% 증가, manager 면 20% 증가시켜서 이름, 업무, 급여, 증가된 급여를 조회
select ename, job, sal, decode( job , 'ANALYST' , sal*1.10, 'CLERK',sal*1.15,'MANAGER',sal*1.20 ) 증가된급여 from emp;



10. 부서별로 급여평군, 최고급여를 조회하는데, 단 급여평균이 높은 순으로 조회하고 급여 평균이 2000이상인 부서만 조회
select deptno, avg(sal), max(sal) from emp group by deptno having avg(sal)>=2000 order by avg(sal) desc; 

11. 같은 업무 내에서 부서별 평균급여, 최고급여, 인원수를 조회
select deptno, avg(sal), max(sal), count(*) from emp group by deptno;

12. 인원수, 보너스에 null 이 아닌 인원수, 보너스의 평균 ( 보너스가 null 이 아닌 평균, 널을 포함한 평균)
등록되어있는 부서의 수 ( 중복제외 ) 를 구하여 조회
select count(distinct(deptno)) 부서수, count(*) 인원수, count(comm) 보너스받는놈수, avg(comm) 받는놈평균보너스, avg(nvl(comm,0)) 안받는놈포함평균보너스  from emp;


13. 부서인원이 4명보다 많은 부서의 부서번호, 인원수, 급여의 합을 조회
select deptno, count(empno), sum(sal) from emp having count(empno)>4 group by deptno ;

14. 급여가 최대 2000 이상인 부서에 대해 부서번호, 평균급여, 급여의 합 을 조회
select deptno, avg(sal), sum(sal), max(sal)  from emp having max(sal)>2000 group by deptno;

15. 최고급여와 최소급여의 차이는 얼마인가
select max(sal)-min(sal)&최소급여 from emp ;
select max(sal)-min(sal)급여차이 from emp ;

16 예시)
년도 count min max avg sum
-----------------------------------------------
80 1 800 800 800 800
81 10 950 5000 2282.5 22825
82 2 1300 3000 2150 4300
83 1 1100 1100 1100 1100

select to_char(hiredate,'YY')년도,count(empno)count, min(sal)min, max(sal)max, avg(sal)avg, sum(sal)sum from emp group by to_char(hiredate,'YY') order by to_char(hiredate,'YY');



17 예시)

total 1980 1981 1982 1983
----------------------------------------
14 1 10 2 1

select count(empno)Total, count(decode(to_char(hiredate,'YYYY'),1980,1980)) "1980", count(decode(to_char(hiredate,'YYYY'),1981,1981)) "1981" , count(decode(to_char(hiredate,'YYYY'),1982,1982)) "1982", count(decode(to_char(hiredate,'YYYY'),1983,1983)) "1983" from emp;  

18 예시)

업무  10 20 30 total
analyst 6000 6000
clerk 1300 1900 950 4150
manager 2450 2975 2850 8275
president 5000 5000
saalesman 5600 5600



select job, sum(decode(deptno,10,sal))"10",sum(decode(deptno,20,sal))"20",sum(decode(deptno,30,sal))"30",sum(sal)Total from emp group by job order by job;

151006 DB 함수

2. FUNCTION

1) Single Row Function : 단일행 함수
1. 문자 함수
Lower(), Upper(), Substr(), Length(), Instr(), Ltrim(), Rtrim(), Translate(), Replace(), Chr(), Ascii()
2. 숫자 함수
Round()반올림, Trunc()버림, Floor()올림, Ceil()내림, Mod()나머지, Power()거듭제곱, Sign()부호, ...
3. 날짜 함수
sysdate. Month_Between(), Add_Months(), Next_Day(), Last_Day(), [Round(), Trunc()]
4. 변환 함수
TO_Char(), To_Date(), To_Number()

5. 기타 함수
nvl(), decode()
6. 정규식 함수(Regular Expression) 함수
Regexp_로 시작하는 함수



2) Aggregate Function : 집합 함수
sum(), avg(), max(), min(), count(), distinct()

3) Annalutic Functions
4) Object Reference Functions
5) Model Functions`



***실습
--------------------

이름이 scott 인 직원의 이름, 부서, 급여를 조회 단, 대소문자 구별없이 검색할 수 있도록 하라.

select ename, deptno, sal from emp where ename='SCOTT' or ename = 'Scott or ename = 'scott' or ename =  'ScoTT' or ename = 'SCott'

select ename, deptno, sal from emp where Upper(ename) = upper('ScoTt');




다음의 주민번호 에서 성별에 해당하는 부분을 추출 하시오.

select Substr('123456-1234567' , 8, 1) from emp;

select Substr('123456-1234567' , 8, 1) from dual;

select Substr('123456-1234567' , 8) from emp;



*****문자열의 길이

select Length('안녕하세요...SQL 연습중입니다.') from dual;



*****문자열의 위치

select Instr('MILLER', 'L') from dual;

select Instr('MILLER', 'L', '1', '1' ) from dual;
    시작 1번째찾은문자

select Instr('MILLER', 'L', '1', '2' ) from dual;
2번째찾은문자

select Instr('MILLER', 'K') from dual; // 찾는값이 없으면 찾는값이 0개라 0이라고나옴

select Instr('MILLER', 'L', '-1', '1' ) from dual; // 시작위치를 뒤에서부터 찾게끔 하려면 -1이라고 써줌 / 결과값은 앞에서부터 4번째라 4

select Instr('MILLER', 'L', '-1', '2' ) from dual;



*****특정 문자열을 제거 ( 왼쪽/ 오른쪽 문자열 제거 )

select ltrim ('MILLER', 'M') from dual;  // 왼쪽에 M이라는글자가있으면 그문자를 지워라

select ltrim ('              MILLER')  from dual;  // 공백을 지워준다 (공백은 지정하지않아도됨)




select translate( 'MILLER', 'L', '*') from dual;  //  L 이라는 문자를 * 로 바꿔준다

select replace( 'MILLER', 'L', '*') from dual;


select sal, translate( sal, '0123456789','영일이삼사오육칠팔구')from emp; // 0=영 1=일 2=이 ...

select sal, replace( sal, '0123456789','영일이삼사오육칠팔구')from emp; // 012... = 영일이...


select replace('JACK and JUE' , 'J', 'BL') from dual; // JACK = J , JUE = BL 

select translate('JACK and JUE' , 'J', 'BL') from dual; // JACK = J , JUE = B 



*****아스키코드

select chr (65), chr (97) from dual; A a

select ascii('A'), ascii('a')from dial; 65 97



*****소수점관리, 나머지, 거듭제곱, 부호

select round(4567.678) from dual; // 소수점반올림  4568

select round(4567.678 , 2 ) from dual; // 2번째자리까지표시 소수점반올림  4567.68

select round(4567.678, -2) from dual; // 소수점반대로 2번째 반올림   4600

select trunc(4567.678 , 0) from dual; // 4567

select trunc(4567.678 , 2) from dual; // 2번째자리에서 버림4567.67

select floor(4567.678) from dual; // 소수점에서 내림 지정 X   4567

select ceil(4567.378 , 2) from dual; // 올림 4568 

select mod(10 / 3) from dual; //  3/10 의 나머지

select power (2, 10) from dual; // 2^10

select sign( 100 ), sign( -100), sign(0) from dual; //



*****날짜함수

select sysdate From dual;

select sysdate +100 from dyal;

select sysdate -10 from dyal;



select sysdate - To_Date('2015/9/7') from dual;

select months_between( sysdate, '2015/1/1') from dual;

select add_maoths(sysdate, 3) from dual; 현재날짜  + 3 월

select next_day('2014/3/16','금')from dual; 2014년 3월 16일이 있던 주의 금요일 

select last_day(sysdate) from dual; 그날짜의 달의 마지막날

select round(sysdate) from dual;

select round(to_date('15/10/20')) from dual;

select round(to_date('15/10/20'),'MONTH') from dual;

select round(to_date('15/10/20'),'YEAR') from dual;



*****변환함수

select ename, sal. to_char(sal) from emp;

select ename, sal, to_char(sal, '$999,999') from dual;

select ename, sal, to_char(sal, 'L999,999') from dual;  // L 현지 로케이션 에 알맞는 단위로 맞춰줌  \999,999

select to_char (sysdate, 'YYYY MM DD HH:MI:SS') from dual;  2015 10 06 12:00:00 



*****nvl() 과 decode()

1) 직원들의 이름, 급여, 커미션, 총급여( 급여 + 커미션 ) 을 조회

select ename, sal, comm, sal + comm as 총급여 from emp;

select ename, sal, comm, sal+nvl(comm, 0 ) as 총급여 from emp;


2) 부서코드가 10번이면 영업부, 그외의 부서는 타부서 라고 출력

select empno, ename, decode( deptno, 10 , 영업부', '타부서' )from emp;


3) 부서코드가 10번이면 영업부, 20번 이면 총무부 그외의 부서는 타부서 라고 출력

select empno, ename, decode( deptno, 10 , 영업부', '20', '총무부', '그외부서' )from emp;



*****집합함수

업무가 salesman인 직원들에 대해 급여의 평균, 최고액, 최저액, 합계를 조회

select avg(sal), max(sal), min(sal), sum(sal), from emp where job like 'SALES%';


직원이 총 몇명인가

select count(*) from emp; // * 필드의 최대값 갯수 14
select count(enpno) from emp; 14
select count (comm) from emp; 4   null값은 안침



**SELECT 의 추가문법
GROUP BY 필드명
HAVING 조건명


부서별로 급여평균, 최고급여, 최저급여, 급여합계를 조회

select deptno, avg(sal), max(sal), min(sal), sum(sal) from emp group by deptno order by sum(sal) desc;

select deptno, avg(sal), max(sal), min(sal), sum(sal), from emp 
// 실행안됨 deptno 는 1실행 집합함수는 14번실행  / 위에껀 그룹으로 묶어줘서 가능



부서별직원수를 조회 

select deptno, count(empno) from emp group by deptno;



각 부서 내에서 업무별 평균 급여, 최고급여 를 조회

select deptno, job, avg(sal), max(sal) from emp group by deptno, job;



전체 급여의 합계가 5000을 초과하는 업무에 대해 급여합계 조회

select job, sum(sal+comm) from emp where sum(sal+comm)>=5000 group by job;

select job, sum(sal) from emp group by job having sum(sal)>5000;



업무가 salesman 이 아닌 다른 업무에 대해 급여 평균을 조회

select job, avg(sal) from emp group by job having job != 'SALESMAN';


select job, avi(sal) from emp where job != 'SALESMAN' group by job;





******DML : INSERT, UPDATE, DELETE

1.계정생성
-id : testUser
-pw : 1111

2.계정에 권한부여
-Connect, Resource

3.testUser계정으로 접속하여 테이블 생성
CREATE TABLE tbltest( id number, name varchar2(10), hiredate date);



1.INSERT
insert into 테이블명[(필드명...)] VALUES(값...)
---------------------------------------------------

insert into tbltest (id, name, hiredate)
values(1, '홍길동', sysdate);

insert into tbltest(id,name) values(2, '임꺽정');

insert into tbltest values(3, '신돌석', '2015/01/01');


2.UPDATE
UPDATE 테이블명

SET 필드명 = 값[,필드명=값,,,,]
[WHERE 조건식]
-----------------------------------------------------

update tbltest set hiredate = sysdate where id = 2;



3.DELETE
DELETE FROM 테이블명 [WHERE 조건식]
-----------------------------------

delete from tbltest where id = 1;