Database/OracleSQL
오라클 MAX, 그룹함수 AVG, GROUP BY, 서브쿼리, ROWNUM, UNION ALL, DECODE, CASE
Jaybon
2020. 3. 25. 16:38
환경
윈도우10 64비트
오라클 18c 익스프레스
스캇 예제
예제를 확인하시려면
https://ondolroom.tistory.com/163
MAX
SELECT MAX(SAL), ENAME
FROM EMP;
MAX는 한줄 ENAME는 여러줄 이기 때문에 오류가 난다
GROUP BY
SELECT MAX(SAL), DEPTNO
FROM EMP
GROUP BY DEPTNO;
-- GROUP BY에 나눌 컬럼을 적고 SELECT에 그룹핑할 컬럼을 적어라
-- 문법은 행의 개수를 맟추는 것
SELECT MAX(SAL), JOB
FROM EMP
GROUP BY JOB;
-- 그룹을 2가지 이상하면 많은 것을 기준으로 그룹
SELECT MAX(SAL), DEPTNO, ENAME
FROM EMP
GROUP BY DEPTNO, ENAME;
DEPTNO를 그룹으로 만들었으나 ENAME가 양이 더 많기때문에 중복으로 나타남
-- 부서별 월급의 총합을 구하고 부서를 오름차순으로 정렬
SELECT SUM(SAL), DEPTNO
FROM EMP
GROUP BY DEPTNO
ORDER BY DEPTNO;
-- 직업별 직원수를 구하라
SELECT COUNT(*), JOB
FROM EMP
GROUP BY JOB;
-- 직업별 연봉의 평균(+소수점 탈락)
SELECT FLOOR(SUM(SAL)/COUNT(JOB)), JOB
FROM EMP
GROUP BY JOB
HAVING JOB != 'MANAGER';
HAVING을 쓰는 이유!
--그룹함수(AVG 등)은 무조건 GROUP BY 다음에 써야한다, 그래서 HAVING을 사용
SELECT DEPTNO, AVG(NVL(SAL,0))
FROM EMP
GROUP BY DEPTNO
HAVING AVG(NVL(SAL,0)) > 2000;
서브쿼리
-- 서브쿼리 (셀렉트 문안에 또 셀렉트가 들어가는 것)
SELECT -- 스칼라 서브쿼리
FROM -- 인라인뷰 서브쿼리
WHERE -- ? 서브쿼리
인라인뷰 서브쿼리
일단 테이블에서 원하는 자료만 추출한다
SELECT ENAME "EN"
FROM EMP;
해당코드를 FROM( 이곳 )에 넣는다
SELECT *
FROM
(
SELECT ENAME "EN"
FROM EMP
)
WHERE EN = 'SMITH';
ROWNUM
--ROWNUM은 하드디스크에서 가져온 순서대로 번호를 매김
SELECT ROWNUM
FROM GOGAK
WHERE ROWNUM > 0 AND ROWNUM < 9;
SELECT MAX(POINT)
FROM GOGAK
WHERE ROWNUM > 0 AND ROWNUM < 9;
UNION ALL
SELECT MAX(POINT)
FROM GOGAK
WHERE ROWNUM > 0 AND ROWNUM < 9
UNION ALL --합치기
--1번부터 불러오지 않으면 NULL이뜬다
SELECT MAX(POINT)
FROM
( -- 서브쿼리
SELECT GNO, POINT, ROWNUM "NO"
FROM GOGAK
)
WHERE NO > 8 AND NO < 21;
위코드를 DECODE나 CASE를 사용해서 만들어본다
DECODE
-- DECODE로 구분하기, DECODE는 부등호를 쓸수 없다
SELECT GNO, GNAME, POINT, DECODE(NO, 1, 1, 2) "NO"
FROM
(
SELECT GNO, GNAME, POINT, CEIL(ROWNUM /9) "NO"
FROM GOGAK
);
CASE
-- CASE로 구분하기
SELECT GNO, GNAME, CASE WHEN NO < 9 THEN 1 ELSE 2 END "NO"
FROM
(
SELECT GNO, GNAME, POINT, ROWNUM "NO"
FROM GOGAK
);
위 코드들이 서브쿼리의 인수가 된다
SELECT NO, MAX(POINT)
FROM
(
SELECT GNO, GNAME, POINT, DECODE(NO, 1, 1, 2) "NO"
FROM
(
SELECT GNO, GNAME, POINT, CEIL(ROWNUM /9) "NO"
FROM GOGAK
)
)
GROUP BY NO;
또는
-- 세로연산의 핵심은 그룹을 만드는 것
SELECT MAX(POINT), G
FROM
(
SELECT point, CASE WHEN rownum < 9 THEN 1 ELSE 2 END "G"
FROM GOGAK
)
GROUP BY G;
-- 5명씩 끊어서 POINT의 합을 구하시오
SELECT SUM(POINT)
FROM
(
SELECT POINT, CEIL(ROWNUM/5) "FIVE"
FROM GOGAK
)
GROUP BY FIVE;
-- 같은 나이의 POINT의 합을 구하시오
SELECT SUM(POINT)
FROM
(
SELECT POINT, SUBSTR(JUMIN, 1, 2) "NAI"
FROM GOGAK
)
GROUP BY NAI;
-- 순위매기기
SELECT ENAME, SAL, ROWNUM
FROM
(
SELECT ENAME, SAL
FROM EMP
ORDER BY SAL DESC
);