일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 그래프 생성 문법
- 데이터분석
- difftime
- 팀스파르타
- 상관관계
- 총과 카드만들기
- loop 문
- 정보획득량
- 빅데이터
- merge
- 막대그래프
- 그래프시각화
- Intersect
- 순위출력
- 데이터분석가
- sqld
- 불순도제거
- max
- 단순회귀 분석
- %in%
- Sum
- 회귀분석 알고리즘
- sql
- count
- Dense_Rank
- 히스토그램 그리기
- 빅데이터분석
- 회귀분석
- if문 작성법
- 여러 데이터 검색
- Today
- Total
ch0nny_log
[빅데이터분석] SQL_TIL8 본문
[TIL 8]_240522
48. PIVOT
예제48. ROW를 COLUMN으로 출력하기 2 (PIVOT)
1. ROW ---------> COLUMN : PIVOT 문 (SUM+DECODE 함수)
2. COLUMN ---> ROW: UNPIVOT 문
Q1. 부서번호, 부서번호 별 토탈월급을 가로로 출력하시오.
select sum(decode(deptno, 10,sal, null)) as "10", sum(decode(deptno, 20, sal, null)) as "20", sum(decode(deptno, 30, sal, null)) as "30" from emp;
** 가로 컬럼 (부서번호_10,20,30)를 알아야 sql을 짤 수 있다는 것이 단점 (PL/SQL, R, 파이썬으로는 쉽게 가능함)
[PIVOT 사용]
select * from (select deptno, sal from emp) pivot (sum(sal) for deptno in (10,20,30) );
- SUM+DECODE 를 사용했 을 때보다 심플학 SQL 작성 가능
- SUB쿼리는 EMP테이블의 모든 컬럼을 가져오는 게 아니고 부서번호와 월급만 조회에서 가져옴
- 가로로 되길 원하는 컬럼을 SUB쿼리에 넣음 (ex. 부서번호별 토탈월급을 가로로 출력하는 결과를 보기위해서 필요한 데이터가 deptno와 sal만 필요로하지 다른 job, hiredate등이 필요하지 않음.)
- 특정 데이터 열만 보고싶을 경우 select 다음 * 이 아닌 특정 데이터를 넣는다.(권장하지는 않음)select "10","20" from (select deptno, sal from emp) pivot (sum(sal) for deptno in (10,20,30) );
문제1. 부서번호, 부서번호별 최대월급을 가로로 출력하시오.
select * from (select deptno, sal from emp) pivot(max(sal) for deptno in(10,20,30));
문제2. 부서번호, 부서번호별 최대월급을 세로로출력하시오.
select deptno, max(sal) from emp group by deptno;
문제3. 부서번호, 부서번호별 평균월급을 가로출력하시오.
select * from (select deptno, sal from emp) pivot (avg(sal) for deptno in(10,20,30)) ;
** pivot 절 안에는 round를 쓸수 없음(select 절에 가능)
select round("10"),round("20"),round("30") from (select deptno, sal from emp) pivot (avg(sal) for deptno in(10,20,30)) ; # as 사용할 때 유의 select round("10"),round("20"),round("30") from (select deptno as 부서번호, sal from emp) pivot (avg(sal) for 부서번호 in(10,20,30)) ;
문제 4. 직업 중복을 제거하여 출력하시오.
select distinct job from emp;
문제 5. 직업, 직업별 토탈월급을 출력하시오(세로)
select job, sum(sal) from emp group by job;
문제 6. 위 문제를 pivot을 사용하 가로로 출력하시오.
select * from (select job, sal from emp) pivot(sum(sal) for job in('ANALYST','CLERK','MANAGER','SALESMAN','PRESIDENT'));
select * from (select job, sal from emp) pivot(sum(sal) for job in('ANALYST' as "ANALYST",'CLERK'as"CLERK",'MANAGER'as"MANAGER",'SALESMAN'as"SALESMAN",'PRESIDENT'as"PRESIDENT"));
문제 7.(복습) EMP19에서 성별, 성별 별 토탈나이를 세로로 출력하시오.
select gender, sum(age) from emp19 where gender is not null group by gender ;
문제 8. (복습) 위 결과를 가로로 출력하시오.
select * from (select gender, age from emp19) pivot( sum(age) for gender in ('남' as"남",'여'as"여") );
문제9. 위 sql을 이용해 토탈나이가 아니라 평균나이로 추출하시오.
select round(avg(decode(gender, '남', age)) )as"남", round(avg(decode(gender, '여', age)))as"여" from emp19; select round("남")as 남, round("여") as 여 from (select gender, age from emp19) pivot( avg(age) for gender in ('남' as"남",'여'as"여") );
문제 10. 세로로는 통신사, 가로로는 성별로 출력하는데 통신사별 평균나이를 출력하시오.
select lower(telecom),round(avg(decode(gender, '남', age)) )as"남", round(avg(decode(gender, '여', age)))as"여" from emp19 where telecom is not null group by lower(telecom) ;
위와 같은 sql이 더 시각화하기에는 더 좋음.
문제 11. 부서번호, 부서번호별 토탈 월급을 가로로 출력하시오.
select sum(decode(deptno, '10', sal)) as"10", sum(decode(deptno, '20', sal)) as"20", sum(decode(deptno, '30', sal)) as"30" from emp;
문제 12. 위 작업에서 직업별 부서번호별 토탈월급이 나오게 추출하시오.
select job, sum(decode(deptno,'10',sal)) as "10", sum(decode(deptno,'20',sal)) as "20", sum(decode(deptno,'30',sal)) as "30" from emp group by job;
문제13. 부서번호, 부서번호별 인원수를 가로로 출력하시오.
select count( decode(deptno, 10, empno)) as"10", count( decode(deptno, 20, empno)) as"20", count( decode(deptno, 30, empno)) as"30" from emp;
문제14. 위의결과를 직업별 부서번호별 인원수를 출력하시오,
select job, count( decode(deptno, 10, empno)) as"10", count( decode(deptno, 20, empno)) as"20", count( decode(deptno, 30, empno)) as"30" from emp group by job;
문제 15. 이름, 통신사, 주소(앞세글자) 추출하시오.
select ename, lower(telecom), substr(address,1,3) from emp19 where telecom is not null ;
문제 16. 통신사, 통신사별 인원수를 다음과 같이 가로로 출력하시오.
select count(decode(lower(telecom), 'sk', ename) )as "sk", count(decode(lower(telecom), 'kt', ename) )as "kt", count(decode(lower(telecom), 'lg', ename) )as "lg", count(decode(lower(telecom), 'lg알뜰', ename) )as "lg알뜰" from emp19;
문제 17. 위 sql앞에 주소3글자를 출력하여 사는곳 별 통신사별 인원수를 다음과 같이 추출하시오.
select substr(address,1,3), count(decode(lower(telecom), 'sk', ename) )as "sk", count(decode(lower(telecom), 'kt', ename) )as "kt", count(decode(lower(telecom), 'lg', ename) )as "lg", count(decode(lower(telecom), 'lg알뜰', ename) )as "lg알뜰" from emp19 where substr(address,1,3) is not null group by substr(address,1,3);
문제 18. 위의 결과를 통신사가 아니라 성별로 추출하시오.
select substr(address,1,3)as 주소, count(decode(gender, '여', ename) )as "여", count(decode(gender, '남', ename) )as "남" from emp19 where substr(address,1,3) is not null group by substr(address,1,3);
문제 19. (난이도중) 위의 결과를 다음과 같이 나오게 하시오
select substr(address,1,3)as 주소, count(decode(gender, '남', ename) )as "남", count(decode(gender, '여', ename) )as "여", count(*) as 총괄 from emp19 where substr(address,1,3) is not null group by substr(address,1,3);
★ 중간 복습 문제 _점심시간★
우리반 테이블에서 나이를 출력하고 나이별로 해당하는 학생들의 이름으로 가로로 출력하는데 이름 옆에 괄호 열고 성별이 출력되게 하시오.
select age, listagg(ename||'('||gender||')',',') from emp19 where age is not null group by age;
49. UNPIVOT
예제49. COLUMN 을 ROW로 출력하기 (UNPIVOT)
1. pivot 문: row(행)----> column(컬럼)
2. unpivot문: column(컬럼) ----> row(행)
컬럼 10 20 30 값 8400 4300 5600
ex) 절도가 많이 일어나느 요일이 언제인가?
-> 컬럼이 데이터로 구성되어야 작성할 수 있다.
문제1. order2테이블을 이용하여 smith는 자전거를 몇대 가지고 있는지 조회하시오.
select bicycle from order2 where ename='SMITH';
문제2. smith가 3대를 가지고있는건 무엇인가? (unpivot 사용)
임의로 작성한 '건수', '아이템' 이 컬럼명이됨select * from order2 unpivot(건수 for 아이템 in(bicycle, camera, notebook));
문제3. 위 결과를 order3 테이블로 만드시오.create table order3 as select * from order2 unpivot(건수 for 아이템 in(bicycle, camera, notebook)) ; select * from order3;
문제4. order3 테이블에서 이름이 smith 인 사원이 3개를 가지고 있는것을 추출하시오.
select ename,아이템,건수 from order3 where ename= 'SMITH' and 건수 = 3
문제5. crime_time의 컬럼을 unpivot문을 이용해서 데이터로 만드시오.
select * from crime_time unpivot(건수 for 시간 in(F0T3, F3T6, F6T9, F9T12, F12T15,F15T18,F18T21,F21T24));
컬럼명 나열하는 함수
DESC CRIME_TIME;
문제6. 위에서 출력되고 있는 결과를 crime_time2라는 테이블로 생성하시오.
DESC CRIME_TIME; drop table crime_time3; create table crime_time2 as select * from crime_time unpivot(건수 for 시간 in(F0T3, F3T6, F6T9, F9T12, F12T15,F15T18,F18T21,F21T24)); commit; select * from crime_time2;
문제7. crime_time2를 조회해서 살인이 가장 많이 일어나는 시간대를 출력하시오.
select * from crime_time2 where crime_type ='살인' order by 건수 desc fetch first 1 rows only; 또는 select crime_type, 시간, 건수, rank() over (order by 건수 desc nulls last) 순위 from crime_time2 where crime_type ='살인';
문제8. 선거범죄가 많이 일어나는 시간대를 1-3위 까지 출력하시오.
select * from crime_time2 where crime_type ='선거범죄' order by 건수 desc fetch first 3 rows only;
★★ 문제9. (복습문제+내일 쪽지 시험 5문제중 하나 형식) 이름과 커미션과 커미션에 대한 순위를 출력하는데 커미션에 대한 순위를 출력할 때 같은 순위가 2명이면 바로 그 다음 순위가 출력되게 하시오 !
select ename, comm, dense_rank() over(order by comm desc nulls last) from emp;
★★ 문제 10. (복습문제 + 내일 쪽지 시험 5문제중 하나 형식)
직업이 SALESMAN 인 사원들의 부서번호를 출력하는데 중복을 제거해서
출력하시오 !
select distinct deptno from emp where job ='SALESMAN';
★★ 문제11. (쪽지시험 5문제중 하나 형식) 오늘날짜에서 100 달 뒤에 돌아오는
금요일의 날짜를 출력하시오 !
select next_day(add_months(TO_DATE('2024-05-22','RRRR-MM-DD'),100), '금요일') from dual; select next_day(add_months(TO_DATE(SYSDATE),100), '금요일') from dual;
50. SUMOVER_누적데이터
예제50. 데이터 분석 함수로 누적 데이터 출력하기(SUM OVER)
Q1. 사원 테이블에서 토탈월급을 출력하시오 !
select sum(sal) from emp;
문제1. 사원 테이블에서 사원이름, 월급, 사원 테이블의 토탈월급이 출력되게 하시오 !
select ename, sal, sum(sal) from emp group by ename, sal;
** 뮨에러는 나지않지만 원하는결과는아님
select ename, sal, sum(sal) over ()as "토탈월급" from emp; group by ename, sal;
괄호안에 뭔가를 써줄 수 있는데 아무것도 안쓰면 전체 토탈월급이 출력됩니다.
문제 2. 이름, 월급, 월급의 누적치를 출력하시오.
select ename, sal, sum(sal) over (order by sal asc) as 누적치 from emp;
문제 3. 사원번호, 이름, 월급, 월급의 누적치를 출력하는데 사원번호 순으로 정렬해서 월급의 누적치가 출력되게하시오.
select ename, sal, sum(sal) over(order by empno asc) as 누적치 from emp;
문제 4. 위의 결과에서 직업이 salesman인사원들의 데이터만 출력되게하시오.
select ename, job,sal, sum(sal) over(order by empno asc) as 누적치 from emp where job='SALESMAN';
위 누적되는 SQL문법은 간략하게 작성한것이고 좀더 자세하게 기술하고 싶으면 다음과 같이 작성해야한다.
select ename, job,sal, sum(sal) over(order by empno rows between unbounded preceding and current row) 누적치 from emp where job='SALESMAN';
윈도우 기준 윈도우방식 설명 ROWS UNBOUNDED PRECEDING 맨 첫번째 행을 가르킴 UNBOUNDED FOLLOWING 맨 마지막을 가르킴 CURRENT ROW 현재 행을 가르킴
문제 5. 우리반 테이블에서 이름, 나이, 나이의 누적치를 출력하는데 학생 번호 순서로 정렬되어 출력되면서 나이가 누적되게하시오,
select ename, age, sum(age) over(order by empno asc) 누적치 from emp19; 또는 select ename, age, sum(age) over(order by empno rows between unbounded preceding and current row) 누적치 from emp19;
문제 6. 위의 결과를 다시 추출하는데 성씨가 김, 이,박씨만출력되게하시오.
select ename, age, sum(age) over(order by empno rows between unbounded preceding and current row) 누적치 from emp19 where substr(ename,1,1) in('김','이','박') and age is not null;
※ 누적데이터 구하는 문법에도 partition by를 쓸 수 있다.
문제 7. 부서번호, 이름, 월급, 월급의 누적치를 출력하시오.
select deptno, ename, sum(sal) over(order by empno asc rows between unbounded preceding and current row)누적치 from emp;
문제 8. 위의 결과에서 부서번호별 각 파티션해서 월급이 누적되게하시오.
select deptno, ename, sum(sal) over(partition by deptno order by empno asc rows between unbounded preceding and current row)누적치 from emp;
문제 9. 성별, 이름, 나이, 나이의 누적치를 출력하는데 성별별로 각각 나이가 누적되게하고 나이가 낮은 학생부터 높은 학생순으로 정렬해서 출력하시오
select age, ename, age, sum(age) over(order by age asc rows between unbounded preceding and current row) as 누적치 from emp19 where age is not null;
문제10. 통신사, 이름, 나이, 나이의 누적치가 출력되게하는데 나이가 낮은 학생부터 높은 학생 순으로 누적이 되게하고 통신사별로 각각 나이를 누적시키시
select lower(telecom), ename, age, sum(age)over(partition by lower(telecom)order by age asc rows between unbounded preceding and current row) 누적치 from emp19;
문제11. 사는지역(주소앞 3글자), 이름, 나이, 나이의 누적치를 출력하는데 나이의 누적치를 출력할 때 사는 지역별로 각각 나이의 누적치가 출력되게하시오.
select substr(address,1,3), ename, age, sum(age) over (partition by substr(address,1,3) order by age asc rows between unbounded preceding and current row) 순위 from emp19;
문제 12. 입사한 년도 4자리, 이름, 월금, 월급의 누적치를 출력하는데 입사한 연도별로 각각 월급이 누적되게하고 월급이 낮은 사원부터 높은 사원순으로 누적되게하시오.
select to_char(hiredate,'RRRR')as 입사년도, ename, sal, sum(sal) over(partition by to_char(hiredate,'RRRR') order by sal asc rows between unbounded preceding and current row) 누적치 from emp;
문제 1. 직업, 직업별 인원수를 가로로 출력하시오.
select count(decode(job, 'SALESMAN', empno)) as "SALESMAN",
count(decode(job, 'CLERK', empno )) as "CLERK",
count(decode(job, 'MANAGER', empno )) as "MANAGER",
count(decode(job, 'PRESIDENT', empno )) as "PRESIDENT",
count(decode(job, 'ANALYST', empno )) as "ANALYST"
from emp;
문제 2. 부서번호,부서번호별 토탈워릅을 출력하는데 부서번호가 10번은 제외하고 부서번호별 토탈월급이 4000이상인 것만 출력하고 부서별 토탈월급이 높은 것 부터 출력하시오.
select deptno, sum(sal)
from emp
where deptno <>'10'
group by deptno
having sum(sal) >=4000
order by sum(sal) desc;
문제3. 이름과 커미션과 커미션에 대한 순위를 출력하는데 커미션에 대한 순위를 출력할 때 같은 순위가 2명이면
바로 그 다음 순위가 출력되게하시오.
select ename, comm, dense_rank()over(order by comm desc nulls last) as 순위
from emp
where comm is not null;
문제4. 오늘날짜에서 100달뒤에 돌아오는 금요일의 날짜를 출력하시오.
select next_day(add_months(sysdate,100),'금요일')
from dual;
문제 5. 직업이 salesman인 사원들의 부서번호를 출력하는데 중복을 제거해서 출력하시오.
select distinct deptno
from emp
where job<>'SALESMAN';
'빅데이터 분석(with 아이티윌) > SQL' 카테고리의 다른 글
[빅데이터분석] SQL_TIL9 (0) | 2024.05.23 |
---|---|
[빅데이터분석] SQL_중간 keyword 정리 (0) | 2024.05.22 |
[빅데이터분석] SQL_TIL7 (0) | 2024.05.20 |
[빅데이터분석] SQL_TIL6 (0) | 2024.05.17 |
[빅데이터분석] SQL_TIL5 (2) | 2024.05.16 |