--TO_NUMBER : 문자 -> 숫자
SELECT TO_NUMBER('100','999') FROM dual;
SELECT TO_NUMBER('100') FROM dual; --포멧문자 생략 가능
--일반 함수
-- NVL(value1,value2) : v1이 null 이면 v2를 사용 , val1과 val2의 자료형을 일치해야함
SELECT ename,sal,NVL(comm,0) commission, NVL((comm*12)+(sal*12),0) "Annual Salary" FROM emp ORDER BY commission;
-- SELECT ename,NVL(comm,'NO commission') commission FROM emp; --자료형이 맞지 않아 사용이 불가능하다
SELECT ename, NVL(TO_CHAR(comm),'NO commission') commission FROM emp; --TO_CHAR로 자료형을 맞춰줘서 사용이 가능함.
-- NVL2(value1,value2,value3)valuel1 이 null 인지 평가 null 이면 value3 , null이 아니면 value2 자료형이 일치하지 않아도 됨.
SELECT ename, NVL2(comm,'commission','no commission') commission FROM emp;
--NULLIF(value1,value2) : 두개의 값이 일치하면 null , 두개의 값이 일치하지 않으면 value1
SELECT NULLIF(LENGTH(ename),LENGTH(job)) "NULLIF" FROM emp; --길이가 같으면 NULL
-- coalesce(value1,value2,value3) : null 값이 아닌 값을 사용 // 자료형을 일치시켜야함
SELECT comm,sal,COALESCE(comm,sal,0) FROM emp; --널을 제외하여 사용
--안시 표준
--case 컬럼 when 비교값 then 결과값
-- when then
-- when then
-- (else 결과값)
-- end
SELECT ename, sal,job, CASE job WHEN 'SALESMAN' THEN sal*0.1 WHEN 'MANAGER' THEN sal*0.2 WHEN 'ANALYST' THEN sal*0.3 ELSE sal*0.4 END "Bonus" FROM emp; --셀러리맨 10프로 매니저 20프로 아날리스트 30프로 나머지 40프로 ="보너스"로 출력
SELECT ename,sal,job, CASE WHEN sal>=4000 AND sal <=5000 THEN 'A' WHEN sal>=3000 AND sal < 4000 THEN 'B' WHEN sal>=2000 AND sal <3000 THEN 'C' WHEN sal>=1000 AND sal <2000 THEN 'D' ELSE 'F' END "GRADE" FROM emp;
-- 오라클 전용
--decode : = 비교만 가능
--decomde(컬럼, 비교값, 반환값,
-- 비교값, 반환값,
-- 비교값, 반환값,
-- 반환값)
SELECT ename, sal ,job, DECODE(job,'SALESMAN',sal*0.1,'MANAGER',sal*0.2,'ANALYST',sal*0.3,sal*0.4) "Bonus" FROM emp;
SELECT ename, sal ,job, DECODE (TRUNC(sal/1000),5,'A',4,'B',3,'C',2,'D',1,'E','F') "GRADE" FROM emp;
-- [실습문제]
-- 9) 이름(소문자로 표시) ,업무, 근무연차(MONTH_BETWEEN)를 출력하시오.
-- 10) 사원이름,월급,월급과 커미션을 더한값을 컬럼명: 실급여라고 해서 출력 단,Null값은 나타나지 않게 .
-- 11) 월급과 커미션을 합친 금액이 2,000이상인 급여를 받는 사원의 이름 업무 월급 커미션 고용날짜를 출력하시오. 단,고용날짜는 1980-12-17 형식으로 출력하시오.
SELECT LOWER(ename), job ,TRUNC(MONTHS_BETWEEN(SYSDATE,hiredate)/12) 근무연차 FROM emp;
SELECT ename,sal,sal+NVL(comm,0) 실급여 FROM emp;
SELECT ename,job,sal,NVL(comm,0) 커미션,TO_char(HIREDATE,'YYYY-MM-DD') 고용날짜 FROM emp where sal+ NVL(comm,0)>=2000 ;
-- 12) DEcode 함수를 사용하여 다음 데이터에 따라 job 열의 값을 기준으로 모든 사원의 등급을 표시하시오. 업무 PRESIDENT 등급 A , 업무 ANALYST 등급 B 업무 MANAGER 등급 C 업무 SALESMAN 등급 D 업무 CLERK 등급 E 기타 F or '0'
SELECT ename ,DECODE(job,'PRESIDENT','A','ANALYST','B','MANAGER','C','SALESMAN','D','CLERK','E','F') 등급 FROM emp;
-- 13) TO_CHAR 를 사용 각 사원에 대한 사원번호, 이름 , 급여 및 15% 인상된 급여를 정수(반올림)로 표시 인상된 급여 레이블 'New Salary' 로 표시
SELECT TO_CHAR(empno,9999) 사원번호,ename 이름,TO_CHAR(sal,9999) 급여,TO_CHAR(sal*1.15,9999) "New Salary" FROM emp;
-- 그룹 함수 : 행 집합 연산을 수행하여 그룹별로 하나의 결과를 산출
--AVG() : null을 제외한 모든 값들의 평균을 반환 / null값은 평균 계산에서 무시.
SELECT ROUND(AVG(sal)) FROM emp;
SELECT AVG(comm) FROM emp;
SELECT AVG(NVL(comm,0)) FROM emp;
-- COUNT() : null을 제외한 값을 가진 모든 레코드의 수를 반환, count(*)형식을 사용하면 널도 계산에 포함
SELECT COUNT(empno) FROM emp;
SELECT COUNT(comm) FROM emp;
SELECT COUNT(NVL(comm,0)) FROM emp;
SELECT COUNT(*) FROM emp;
SELECT COUNT(*) FROM emp WHERE deptno =10;
-- MAX() : 레코드 내에 있는 여러 값 중 가장 큰 값을 반환
SELECT MAX(sal) FROM emp;
SELECT MAX(ename) FROM emp;
-- MIN() : 레코드 내에 있는 여러 값 중 가장 작은 값을 반환
SELECT MIN(sal) FROM emp;
SELECT MIN(ename) FROM emp;
-- SUM() : 레코드들이 포함하고 있는 모든 값을 더하여 반환
SELECT SUM(sal) FROM emp;
SELECT ROUND(AVG(sal)),MAX(sal),MIN(sal),SUM(sal) FROM emp;
--SELECT deptno,ROUND(AVG(sal)),MAX(sal),MIN(sal),SUM(sal) FROM emp; // 사용불가 개별함수라서
--GROUP BY : HAVING
SELECT deptno,ROUND(AVG(sal)),MAX(sal),MIN(sal),SUM(sal) FROM emp GROUP BY deptno;
--다중 열에서 GROUP BY 사용
SELECT deptno,job,sum(sal) FROM emp GROUP BY deptno,job ORDER BY deptno; --부서별로 묶고 직업별로 묶고
SELECT deptno,job,sum(sal) FROM emp WHERE deptno=10 GROUP BY deptno,job ORDER BY deptno;
--//그룹 처리 결과를 제한하고자 할 때 having 절 이용 where 절에서는 집합함수를 사용할 수 없고 having 절을 이용
--조건을 체크하기 위해서 where절을 사용하는데 where 절에는 그룹함수를 사용할 수 없음.
--오류 발생
--SELECT deptno,ROUND(AVG(sal)) FROM emp WHERE ROUND(AVG(sal))>=2000 GROUP BY deptno;
SELECT deptno,ROUND(AVG(sal)) FROM emp GROUP BY deptno HAVING ROUND(AVG(sal))>=2000;
-- HAVING절 이용 : HAVING 절에 알리아스 사용 x
SELECT deptno,MAX(sal) "MaxSal" FROM emp GROUP BY deptno HAVING MAX(sal) >3000;
--그룹 함수 중첩
SELECT MAX(AVG(sal)) FROM emp GROUP BY deptno;
-- 그룹함수 이용하기 분기별로 입사한 사원의 수
-- EXTRACT() 함수를 이용하여 입사 일자로부터 월을 구함.
-- 3으로 나눈 값을 올림 처리하여 각 월의 분기를 계산
SELECT CEIL( EXTRACT(MONTH FROM HIREDATE)/3) As quarter, COUNT(empno) as count_member FROM emp GROUP BY CEIL( EXTRACT(MONTH FROM HIREDATE)/3); --1번방법
SELECT TO_CHAR(hiredate,'Q') As quarter, COUNT(empno) AS count_member FROM emp GROUP BY TO_CHAR(hiredate,'Q') ORDER BY quarter; --2번방법 Q는 분기를 나타냄
--[실습문제]
-- 1) 모든 사원의 급여 최고액,최저액,총액 및 평균액을 표시 MAXIMUM MINIMUM SUM 밑 average로 지정, 결과를 정수로 반올림하고 세자리 단위로 ,를 명시하시오.
--2) 업무가 동일한 사원 수를 표시하는 질의어를 작성하시오
SELECT TO_CHAR(MAX(sal),'9,999') "MAXIMUM", TO_CHAR(MIN(sal),'9,999') "MINIMUM" ,TO_CHAR(SUM(sal),'99,999') "sum",TO_CHAR(ROUND(AVG(sal)),'9,999') "average" FROM emp ;
SELECT job,count(job) FROM emp GROUP BY job;
-- 3) 30번 부서의 사원수를 구하기
-- 4) 업무별 최고 월급을 구하고 업무,최고 월급을 출력
-- 5) 20번부서의 급여 합계를 구하고 급여 합계 금액 출력
-- 6) 부서별로 지급되는 총월급에서 금액이 7,000이상인 부서번호,총월급을 출력
SELECT count(*) FROM emp WHERE deptno=30;
--SELECT deptno,count(deptno) FROM emp GROUP BY deptno HAVING deptno=30; // 부서명까지 표기
SELECT job,Max(sal) FROM emp GROUP BY job ;
SELECT deptno,sum(sal) FROM emp GROUP BY deptno HAVING deptno=20;
SELECT deptno,sum(sal) FROM emp GROUP BY deptno HAVING sum(sal) >= 7000;
-- 7)업무별로 사원번호가 제일 늦은 사람을 구하고 그 결과 내에서 사원번호가 79로 시작하는 결과만 보여주시오.
SELECT job, MAX(EMPNO) FROM emp WHERE EMPNO like '79%' GROUP BY job; --1번방법
SELECT job, MAX(EMPNO) FROM emp GROUP BY job HAVING MAX(EMPNO) like '79%' ; --2번방법
-- 8)업무별 총월급을 출력하는데 업무가 MANAGER인 사원들은 제외하고 총월급이 5,000보다 큰 업무의 총월급만 출력
SELECT job,sum(sal) FROM emp GROUP BY job HAVING sum(sal) > 5000 and job !='MANAGER'; --1번방법
SELECT job,sum(sal) FROM emp WHERE job NOT IN 'MANAGER' GROUP BY job HAVING sum(sal) > 5000 ; --2번방법
SELECT job,sum(sal) FROM emp WHERE job <> 'MANAGER' GROUP BY job HAVING sum(sal) > 5000 ; --3번방법
-- 9)업무별로 사원의 수가 4명이상인 업무와 인원수를 출력
SELECT job,count(empno) FROM emp GROUP BY job HAVING COUNT(empno)>=4;
-- 10)사원수가 5명이 넘는 부서의 부서번호와 사원수를 구하기
SELECT deptno,count(empno) FROM emp GROUP BY deptno HAVING COUNT(empno)>5;
-- 11)부서별 급여평균을 구할 때 소수점 3자리에서 반올림해서 2자리까지 구하고 부서번호, 부서평균을 출력하시오.
SELECT deptno,TO_CHAR(AVG(sal),'9999.99') FROM EMP GROUP BY deptno ;
SELECT deptno,ROUND(AVG(sal),2) FROM EMP GROUP BY deptno ;
-- 12)분기별로 입사한 사원수를 구하는데 2분기에 입사한 사원수만 구하시오. (TO_CHAR() 사용하기)
SELECT TO_CHAR(hiredate,'Q') 분기 ,COUNT(empno) "입사한 사원수" FROM emp GROUP BY TO_CHAR(hiredate,'Q') HAVING TO_CHAR(hiredate,'Q')=2 ; --q는 분기별로 나타냄
SELECT TO_CHAR(hiredate,'Q') 분기 ,COUNT(empno) "입사한 사원수" FROM emp WHERE TO_CHAR(hiredate,'Q')=2 GROUP BY TO_CHAR(hiredate,'Q') ; --q는 분기별로 나타냄
'프로그래밍 > sql,php' 카테고리의 다른 글
sql> PL/SQL 2일차 (0) | 2018.11.22 |
---|---|
sql>오라클 DB수업 6일차 + PL/SQL START (0) | 2018.11.21 |
sql> 오라클db 수업 4일차 (0) | 2018.11.19 |
sql> 오라클 sql 수업 2일차 (0) | 2018.11.15 |
sql> 오라클 sql 수업 1일차 (0) | 2018.11.14 |