짝수 해와 홀수 해에 입사한 사원의 정보 구하기
SELECT CASE MOD(EXTRACT(YEAR FROM hiredate),2) WHEN 0 THEN '짝수 연도'
ELSE '홀수 연도'
END AS YEAR,
COUNT(empno) AS employee_number
FROM emp GROUP BY MOD(EXTRACT(YEAR FROM hiredate),2);
1981년에 입사한 사원들의 목록으로부터 분기별 입사자의 수를 구함
SELECT TO_CHAR(hiredate,'Q') AS "Quarter",COUNT(empno) AS employee_number
FROM emp where extract(year from HIREDATE) = 1981
GROUP BY TO_CHAR(hiredate,'Q') ORDER BY "Quarter";
[실습문제]
1.모든 사원의 급여 최고액,최저액,총액 및 평균액을 표시하시오.열 레이블을 각각 maximum, minimum, sum 및 average로 지정하고 결과를 정수로 반올림하고 세자리 단위로 ,를 명시하시오.
[1]
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;
[2] : ROUND 제거, format형식에 소숫점이 없어서
SELECT TO_CHAR(MAX(sal),'9,999') maximum, TO_CHAR(MIN(sal),'9,999') minimum,
TO_CHAR(SUM(sal),'99,999') sum, TO_CHAR(AVG(sal),'9,999') average
FROM emp;
SELECT MAX(sal+NVL(comm,0)) max, MIN(sal+NVL(comm,0)) min,
ROUND(AVG(sal+NVL(comm,0)),1) avg
FROM emp;
SELECT job,COUNT(*) FROM emp GROUP BY job;
SELECT COUNT(*) FROM emp WHERE deptno=30; --부서번호를 명시하지 않은 경우
SELECT deptno,COUNT(*) FROM emp WHERE deptno=30 GROUP BY deptno; --부서번호ㅡ사원수 명시
SELECT deptno,COUNT(*) FROM emp GROUP BY deptno HAVING deptno=30;
--둘다 가능, where절이 보편적(having은 그룹함수 일 때 사용)
SELECT job,MAX(sal) FROM emp GROUP BY job;
SELECT SUM(sal) FROM emp WHERE deptno=20;
SELECT deptno,SUM(sal) FROM emp GROUP BY deptno HAVING SUM(sal)>=9000;
SELECT job,MAX(empno) FROM emp GROUP BY job HAVING MAX(empno) LIKE '79%'; --이게 정답
SELECT job,MAX(empno) FROM emp WHERE empno LIKE '79%' GROUP BY job; --이것도 결과는 같음
SELECT job,SUM(sal) FROM emp WHERE job != 'MANAGER' GROUP BY job HAVING SUM(sal)>5000;
SELECT job,COUNT(*) FROM emp GROUP BY job HAVING COUNT(*)>=4;
RANK(조건값) WITHIN GROUP (ORDER BY 조건값 컬럼명 [ASC|DESC]) : 특정 데이터의 순위 확인하기
- [주의] RANK 뒤에 나오는 데이터와 ORDER BY 뒤에 나오는 데이터는 같은 컬럼이어야 한다.
SELECT RANK('SMITH') WITHIN GROUP (ORDER BY ename) "RANK" FROM emp;
SELECT empno,ename,sal,RANK() OVER (ORDER BY sal) "RANK_ASC",
RANK() OVER (ORDER BY sal DESC) "RANK_DESC" FROM emp; --내림차순,오름차순 정렬
10부서에 속한 직원들의 사번과 이름,급여,해당 부서 내의 급여 순위를 출력
SELECT empno,ename,sal,RANK() OVER (ORDER BY sal DESC) "RANK" FROM emp WHERE deptno=10;
사원번호,이름,급여,부서번호,부서별 급여 순위를 출력
SELECT empno,ename,sal,deptno,
RANK() OVER (PARTITION BY deptno ORDER BY sal DESC) "RANK" FROM emp;
Catesion Product(카티션 곱)
검색하고자 했던 데이터뿐 아니라 조인에 사용된 테이블들의 모든 데이터가 반환되는 현상
SELECT * FROM emp,dept; --emp,dept테이블이 합쳐져 중복데이터가 생김 : JOIN필요
SELECT emp.ename,dept.dname FROM emp,dept WHERE emp.deptno=dept.deptno;
--두 테이블 모두 같은 컬럼이 있어야 함(여기선 deptno)
SELECT e.ename,d.dname FROM emp e,dept d WHERE e.deptno=d.deptno;
SELECT ename,d.deptno,dname FROM emp e,dept d WHERE e.deptno=d.deptno;
--두 테이블에 같은 컬럼이 있는 경우는 알리아스 생략 불가
SELECT e.ename,d.dname FROM emp e,dept d
WHERE e.deptno=d.deptno AND e.ename='ALLEN'; --AND로 조건 추가 입력
SELECT e.ename,e.sal,d.dname FROM emp e,dept d
WHERE e.deptno=d.deptno AND e.sal BETWEEN 3000 AND 4000;
- 비동등조인 : 동등조인이 안된다고 하더라도 같은 조건의 데이터여야 한다. emp.sal=salgrade로 대응되기 때문에 가능
SELECT e.ename,e.sal,s.grade FROM emp e,salgrade s WHERE e.sal BETWEEN s.losal AND s.hisal;
사원 이름과 해당 사원의 관리자 이름 구하기(관리자가 없는 사원 제외)
SELECT e.ename 사원이름,m.ename 관리자이름 FROM emp e,emp m WHERE e.mgr=m.empno;
--e: 사원정보,m: 관리자번호
SELECT DISTINCT e.deptno,d.deptno FROM emp e,dept d WHERE e.deptno(+)=d.deptno;
SELECT e.ename 사원이름,m.ename 관리자이름 FROM emp e,emp m WHERE e.mgr=m.empno(+);
--누락행의 반대테이블
SELECT e.ename,d.deptno FROM emp e INNER JOIN dept d ON e.deptno=d.deptno;
SELECT e.ename,d.deptno FROM emp e JOIN dept d ON e.deptno=d.deptno;
SELECT e.ename,d.dname FROM emp e JOIN dept d ON e.deptno=d.deptno WHERE e.ename='ALLEN';
SELECT e.ename,d.dname FROM emp e JOIN dept d USING(deptno) WHERE e.ename='ALLEN';
SELECT e.ename,deptno FROM emp e JOIN dept d USING(deptno);
--오류: ALIAS사용X, USING명령어로 하나로 합침
SELECT ename,deptno,dname FROM emp JOIN dept USING(deptno);
사원 이름과 해당 사원의 관리자 이름 구하기(관리자가 없는 사원읜 제외)
SELECT e.ename name,m.ename manager_name FROM emp e JOIN emp m ON e.mgr = m.empno;
--USING 사용 불가
SELECT DISTINCT(e.deptno),d.deptno FROM emp e RIGHT OUTER JOIN dept d ON e.deptno=d.deptno;
--_1로 누락된거 확인하고 RIGHT OUTER 추가하여 빈 컬럼도 추가
SELECT e.ename name,m.ename manager_name FROM emp e LEFT OUTER JOIN emp m ON e.mgr=m.empno;
[실습문제]
1.모든 사원의 이름,부서번호,부서이름을 표시하시오.(emp,dept)
오라클 전용
SELECT e.ename,e.deptno,d.dname FROM emp e,dept d WHERE e.deptno=d.deptno;
표준 SQL
SELECT e.ename,d.deptno,d.dname FROM emp e JOIN dept d ON e.deptno=d.deptno;
SELECT ename,deptno,dname FROM emp JOIN dept USING(deptno);
오라클 전용
SELECT e.ename,e.job,d.dname,d.loc FROM emp e,dept d WHERE e.deptno=d.deptno AND e.job='MANAGER';
표준 SQL
SELECT e.ename,e.job,d.dname,d.loc
FROM emp e JOIN dept d ON e.deptno=d.deptno
WHERE e.job='MANAGER';
SELECT ename,job,dname,loc FROM emp e JOIN dept USING(deptno) WHERE job='MANAGER';
오라클 전용
SELECT e.ename,e.sal,d.dname,d.loc FROM emp e,dept d
WHERE e.deptno=d.deptno AND e.comm IS NOT NULL AND e.sal>=1600;
표준 SQL
SELECT e.ename,e.sal,d.dname,d.loc
FROM emp e JOIN dept d ON e.deptno=d.deptno
WHERE e.comm IS NOT NULL AND e.sal>=1600;
SELECT ename,sal,dname,loc FROM emp JOIN dept USING(deptno) WHERE comm IS NOT NULL AND sal>=1600;
오라클 전용
SELECT e.ename,e.job,d.deptno,d.dname
FROM emp e,dept d WHERE e.deptno=d.deptno AND d.loc='CHICAGO';
표준 SQL
SELECT e.ename,e.job,d.deptno,d.dname
FROM emp e JOIN dept d ON e.deptno=d.deptno
WHERE d.loc='CHICAGO';
SELECT ename,job,deptno,dname FROM emp JOIN dept USING(deptno) WHERE loc='CHICAGO';
오라클 전용
SELECT d.loc,COUNT(e.empno) emp_member
FROM emp e,dept d WHERE e.deptno(+)=d.deptno
GROUP BY d.loc HAVING COUNT(e.empno)<=5 ORDER BY emp_member;
표준 SQL
SELECT d.loc,COUNT(e.empno) emp_member
FROM emp e RIGHT OUTER JOIN dept d ON e.deptno=d.deptno
GROUP BY d.loc HAVING COUNT(e.empno)<=5 ORDER BY emp_member;
SELECT loc,COUNT(empno) emp_member FROM emp RIGHT OUTER JOIN dept USING(deptno)
GROUP BY loc HAVING COUNT(empno)<=5 ORDER BY emp_member;
오라클 전용
SELECT e.ename "employee",e.empno "emp#",m.ename "manager",e.mgr "mgr#"
FROM emp e, emp m WHERE m.empno=e.mgr;
표준 SQL
SELECT e.ename "employee",e.empno "emp#",m.ename "manager",e.mgr "mgr#"
FROM emp e INNER JOIN emp m ON m.empno=e.mgr;
7.관리자보다 먼저 입사한 모든 사원의 이름, 사원 입사일, 관리자의 이름, 관리자 입사일과 함께 표시하고 열 레이블을 각각 employee,emp hired,manager,mgr hired로 지정하시오.
오라클 전용
SELECT e.ename "employee",e.hiredate "emp hired",m.ename "manager",m.hiredate "mgr hired"
FROM emp e,emp m WHERE m.empno=e.mgr AND e.hiredate<m.hiredate;
표준 SQL
SELECT e.ename "employee",e.hiredate "emp hired",m.ename "manager",m.hiredate "mgr hired"
FROM emp e JOIN emp m ON e.mgr=m.empno WHERE e.hiredate<m.hiredate;
오라클 전용
SELECT e.ename "employee",e.empno "emp#",m.ename "manager",m.empno "mgr#"
FROM emp e, emp m WHERE e.mgr=m.empno(+) ORDER BY e.empno;
표준 SQL
SELECT e.ename "employee",e.empno "emp#",m.ename "manager",m.empno "mgr#"
FROM emp e LEFT OUTER JOIN emp m ON e.mgr=m.empno ORDER BY e.empno;
오라클 전용 : JOIN 기준을 급여,실급여로 조인하라는 것을 말하지 않음
SELECT e.empno 사원번호,e.ename 사원이름,e.sal*12 연봉,e.sal+e.comm 실급여,s.grade 급여등급,d.dname 부서명
FROM emp e,dept d,salgrade s
WHERE e.deptno=d.deptno AND e.sal BETWEEN s.losal AND s.hisal AND e.comm IS NOT NULL;
표준 SQL
SELECT e.empno 사원번호,e.ename 사원이름,e.sal*12 연봉,e.sal+e.comm 실급여,s.grade 급여등급,d.dname 부서명
FROM emp e JOIN dept d ON e.deptno=d.deptno JOIN salgrade s
ON e.sal BETWEEN s.losal AND s.hisal WHERE e.comm IS NOT NULL;