Oracle DBA/SQL

20230628 (5) SQL 047 : ROW를 COLUMN으로 출력하기 1(SUM+DECODE)

Nuez 2023. 6. 28. 14:39
반응형

1. 행(row) -> 컬럼(column) : sum + decode 또는 pivot문

2. 컬럼(column) -> 행(row) : unpivot문


예제. 부서번호, 부서번호별 토탈 월급을 출력하시오. 

SELECT deptno, SUM(sal)
FROM emp
GROUP BY deptno;


목표)  (답변 : 문제 233에 있음)

위의 예제에서 출력되는 행의 데이터가 컬럼이 되어서 다음과 같이 출력되게 하시오. 

10 20 30
8750 10875 9400

 


목표 문제를 위한 과정 1. 

문제 232. 부서번호, decode를 이용해서 부서번호가 10번이면 월급이 나오게, 아니면 0이 나오게 하시오. 

SELECT deptno, DECODE(deptno, 10, sal, 0) AS "10"
FROM emp;


목표 문제를 위한 과정 2.  

위의 결과에서 deptno컬럼은 제외하고, 전체 총합이 나오게 하시오. 

SELECT sum(DECODE(deptno, 10, sal, 0)) AS "10"
FROM emp;


목표 문제를 위한 과정 3.

문제 233. 위의 출력되는 결과 옆에 20번과 30번도 같이 출력하시오. 

SELECT SUM(DECODE(deptno, 10, sal, 0)) AS "10",
        SUM(DECODE(deptno, 20, sal, 0)) AS "20",
        SUM(DECODE(deptno, 30, sal, 0)) AS "30"
FROM emp;

참고 : 

sum(DECODE(deptno, 10, sal, 0))라고 작성하는 것보다 

sum(DECODE(deptno, 10, sal, null)) 라고 작성하는 것이 더 효율적임. 

 

위의 경우 : deptno가 10이 아닌 경우 0으로 설정하고 sum 연산으로 전체 데이터 합산 ( a의 월급 + 0 + b의 월급 + 0 + ...) 

아래의 경우 : deptno가 10이 아닌 경우 null로 설정하면, null부분 무시하고, 있는 값끼리 sum 연산으로 전체 데이터 합산 


문제 236.(세로 출력) 직업, 직업별 토탈 월급을 출력하시오. 

SELECT job, SUM(sal)
FROM emp
GROUP BY job;


문제 237. (가로 출력) 직업, 직업별 토탈 월급을 출력하시오. 

SELECT SUM(DECODE(job,'SALESMAN',sal)) AS SALESMAN,
        SUM(DECODE(job,'CLERK',sal))AS CLERK,
        SUM(DECODE(job,'ANALYST',sal))AS ANALYST,
        SUM(DECODE(job,'MANAGER',sal))AS MANAGER,
        SUM(DECODE(job,'PRESIDENT',sal)) AS PRESIDENT
FROM emp;

직업별로 하나 하나 하드코딩해야 하는 단점있음. 

PL/SQL문 procedure로 처리하면 굳이 직업을 일일이 명시하지 않아도 된다고 함. 

(아직 더 공부해야 할 부분)


문제 238. ( 세로 출력) 입사년도(4자리), 입사년도별 토탈월급을 출력하시오. 

SELECT to_char(hiredate,'RRRR') as 입사년도, SUM(sal) as 토탈월급
FROM emp
GROUP BY to_char(hiredate,'RRRR')
ORDER BY 1;


문제 239. (가로 출력) 입사년도(4자리), 입사년도별 토탈월급을 출력하시오.

SELECT SUM(DECODE(to_char(hiredate,'RRRR'),'1980',sal)) AS "1980",
SUM(DECODE(to_char(hiredate,'RRRR'),'1981',sal)) AS "1981",
SUM(DECODE(to_char(hiredate,'RRRR'),'1982',sal)) AS "1982",
SUM(DECODE(to_char(hiredate,'RRRR'),'1983',sal)) AS "1983"
FROM emp;


문제240. 위의 결과에서 직업도 앞에 추가하고 직업별로 group by하시오. 

SELECT job, 
	SUM(DECODE(to_char(hiredate,'RRRR'),'1980',sal)) AS "1980",
	SUM(DECODE(to_char(hiredate,'RRRR'),'1981',sal)) AS "1981",
	SUM(DECODE(to_char(hiredate,'RRRR'),'1982',sal)) AS "1982",
	SUM(DECODE(to_char(hiredate,'RRRR'),'1983',sal)) AS "1983"
FROM emp
GROUP BY job;