일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- SWEA
- 클라이언트
- 자바
- 오름차순 정렬
- 알고리즘
- 백준 N과 M 자바
- 프로그래머스 자바
- 스프링부트 도커 배포
- COS Pro
- 백준
- 프로그래머스 문자열 정렬
- Stack
- 스프링부트 도커
- Queue
- 문자열
- 스택
- Programmers
- StringTokenizer
- 이진수 변환
- java
- 프로그래머스
- Lv1
- 큐
- 스프링부트 도커로 배포
- 프로그래머스 풀이
- 버퍼
- index of
- lv0
- 삼각형의 완성조건
- lv2
- Today
- Total
mun dev
[Oracle] 분석 함수(Analytic Function) 본문
Analytic Function
- Row들의 집합으로 Partition이라는 Result Set을 만들며 연산의 범위를 결정하기 위해 각각 Row들을 대상으로 Data Sliding Window를 구성
Analytic Function 수행 과정
- Joins, Where, Group by, Having 등의 수행으로 Data를 추출
- Analytic Function이 이용할 수 있는 Result Set 생성,
- Order by 절이 있다면 Order by를 수행하여 최종 Result Set 반환
User Defined Function을 정의하여 Over 절과 같이 사용가능
Analytic Function 예
select deptno, sum(sal) over (order by deptno)
from emp;
Category
Type | 설명 | 예 | 방법 |
Ranking Function | 대상 집합에 대해 특정 컬럼을 기준으로 순위나 등급을 매기는 Analytic Function | 각 회원사 영업점 별 거래량 상위 10위안에 포함되는 계조라를 찾아라 | RANK, DENSE_RANK, TOP_N, BOTTOM_N, NTILE, CUMI_DEST, PRCENT_RANK, ROW_NUMBER |
Windowing Function |
Current row를 기준으로 지정된 window 내의 row들을 대상으로 집단화(aggregation)을 수행하여 여러가지 유용한 집계 정보를 구하는 Analytic Function류 | 영업점별로 거래량 누적치를 나타내라 | SUM, AVG, MIN, MAX, STDDEV, VARIANCE, COUNT, FIRST_VALUE, LAST_VALUE |
Reporting Function | 서로 다른 두 가지 aggregation level을 비교하고자 하는 목적으로 사용하는 Analytic Function | 영업점 거래량이 회원사에서 차지하는 비율을 나타내라 | RATIO_TO_REPORT |
LEAD/LAG | 서로 다른 두 row 값 비교 | 2009년 6월, 특정 영업점의 거래량에 대한 작년 거래량 대비 증가비율 나타내기 | LAG, LEAD |
예시 데이터 삽입
create table sales_tables
(sales_person varchar2(15),
region varchar(10),
amount number(10));
insert into sales_tables values('Davis', 'East', 100);
insert into sales_tables values('Baker','East',89);
insert into sales_tables values('Smith','East',89);
insert into sales_tables values('Fitzpatrik','East',75);
insert into sales_tables values('Jones','West',98);
insert into sales_tables values('Peterson','West',85);
insert into sales_tables values('Lee','West',77);
commit;
RANK()
각 row마다 순위를 매겨주는 함수로 Partition 내에서 Order by 절에 명시된 대로 정렬한 후 순위를 의미하고, 1부터 시작하며 동일한 순위를 가지며 동일한 순위의 수만큼 다음 순위는 건너 뛴다.
select sales_person, region, amount,
rank() over(partition by region order by amount desc) as rank
from sales_tables;
TOP_N / BOTTOM_N
RANK 함수 작성시 해당하는 순위만 출력하기 위해 사용하는 함수
SELECT *
FROM (SELECT SALES_PERSON,
REGION,
AMOUNT,
RANK() OVER(PARTITION BY REGION ORDER BY AMOUNT DESC) AS RANK
FROM SALES_TABLES) A
WHERE RANK <= 2;
NTILE()
NTILE 함수는 정렬된 PARTITON을 BUCKET 이라 불리는 그룹별로 나누고 PARTITION 내의 각 ROW등을 BUCKET에 배치하는 함수로 각 BUCKET에는 동일한 수의 ROW가 배치된다.
SELECT SALES_PERSON, AMOUNT, NTILE(4) OVER(ORDER BY AMOUNT DESC) AS NTILE
FROM SALES_TABLES;
ROW_NUMBER()
ROW_NUMBER는 각 PARTITION 내에서 ORDER BY 절에 의해 정렬된 순서로 유일한 값을 돌려주는 함수로 ROWNUM과는 관계가 없다.
SELECT SALES_PERSON, AMOUNT, ROW_NUMBER() OVER(ORDER BY AMOUNT DESC) AS RN
FROM SALES_TABLES;
Windowing
- 정렬된 순서에 따라 누적, 증감, 평균값 등을 각각 Row에 대하여 반환
- ROWS | RANGE: ROW 또는 논리적인 범위로 WINDOW를 지정
- BETWEEN … AND: WNDOW에서 START POINT와 END POINT를 지정
- UNBOUNDED PRECEDING: PARTITION의 첫 번째 ROW에서 WINDOW가 시작
- UNBOUNDED FOLLOWING: PARTITION의 마지막 ROW에서 WINDOW가 끝남
SELECT DEPTNO,
JOB,
EMPNO,
ENAME,
HIREDATE,
SAL,
SUM(SAL) OVER(PARTITION BY DEPTNO ORDER BY JOB ROWS UNBOUNDED PRECEDING) 누계
FROM EMP;
Windowing 예제 데이터 삽입
create table ledger (
acct_number varchar(10), trans_date date, trans_amount number(10,2));
insert into ledger values('73829',to_date('19981101','yyyymmdd'),113.45);
insert into ledger values('73829',to_date('19981105','yyyymmdd'),-52.01);
insert into ledger values('73829',to_date('19981113','yyyymmdd'),36.25);
insert into ledger values('73829',to_date('19981205','yyyymmdd'),12.10);
insert into ledger values('73829',to_date('19981213','yyyymmdd'),50.10);
insert into ledger values('82930',to_date('19981101','yyyymmdd'),10.56);
insert into ledger values('82930',to_date('19981121','yyyymmdd'),32.55);
insert into ledger values('82930',to_date('19981129','yyyymmdd'),-5.02);
insert into ledger values('82930',to_date('19981212','yyyymmdd'),10.02);
insert into ledger values('82930',to_date('19981221','yyyymmdd'),20.05);
commit;
Cumulative Aggregation
각 파티션의 시작 위치가 Window의 사작 위치가 되고,현재 Row의 물리적 또는 논리적 위치가 Window의 종료 위치가 되어 여기에 해당하는 집계함수를 적용하는 형태
SELECT ACCT_NUMBER,
TRANS_DATE,
TRANS_AMOUNT,
SUM(TRANS_AMOUNT) OVER(PARTITION BY ACCT_NUMBER ORDER BY TRANS_DATE ROWS UNBOUNDED PRECEDING) AS BALANCE
FROM LEDGER
ORDER BY ACCT_NUMBER, TRANS_DATE;
Moving Aggregation
각 파티션 내의 현재 row의 물리적 또는 논리적 위치가 윈도우의 종료위치가 되고, 이 종료 위치를 기준으로 offset을 적용하여 시작위치가 결정되고 여기에 해당하는 집계함수를 적용하는 형태
SELECT ACCT_NUMBER,
TRANS_DATE,
TRANS_AMOUNT,
AVG(TRANS_AMOUNT) OVER(PARTITION BY ACCT_NUMBER ORDER BY TRANS_DATE RANGE INTERVAL '7' DAY PRECEDING) AS MAVG_7DAY
FROM LEDGER;
Reporting: RATIO_TO_REPORT
RETIO_TO_REPORT 함수는 Window 내의 합계에 대한 비율을 계산하는 함수
SELECT DEPTNO,
JOB,
SUM(SAL) SUM_SAL,
SUM(SUM(SAL)) OVER(PARTITION BY DEPTNO) SUM_TOTAL,
RATIO_TO_REPORT(SUM(SAL)) OVER(PARTITION BY DEPTNO) RATIO_TO_SUM
FROM EMP
GROUP BY DEPTNO, JOB;
LAG/LEAD
오름차순 또는 내림차순으로 정렬된 파티션 내에서 상대적으로 상위 또는 하위에 위치하고 있는 특정 로우의 컬럼 값을 offset 지정에 의해 참조
파티션 내에서 참조할 로우가 없을 경우 지정한 값(default = NULL) 으로 출력
SELECT DEPTNO,
EMPNO,
SAL,
LAG(SAL, 1) OVER(PARTITION BY DEPTNO ORDER BY SAL) AS SAL_LAG,
LEAD(SAL, 1) OVER(PARTITION BY DEPTNO ORDER BY SAL) AS SAL_LEAD
FROM EMP;
Analytic Function의 장점
- Query Speed의 향상
- Self-join, 절차적 로직으로 표현한 것을 native SQL에서 바로 적용할 수 있도록 하여 Join이나 프로그램의 Over head를 줄임
- 향상된 개발 생산력
- 간결한 SQL로 복잡한 분석 작업을 수행 가능하며, 유지보수가 간편하여 생산성 향상
- 이해 및 활용이 용이
- 기존 SQL Syntax를 그대로 따르기 때문에 ANSI SQL로 채택
Reference.
'DB > Oracle' 카테고리의 다른 글
[Oracle] For update 란? 사용법 (0) | 2024.07.20 |
---|---|
[PL SQL] 함수(Function) 사용법 (0) | 2024.02.27 |
[PL SQL] 프로시저(PROCEDURE) 사용법 (0) | 2024.02.27 |
[PL SQL] PL SQL이란? PL SQL 블록(BLOCK)의 구조 (1) | 2024.02.27 |
[Oracle] 오라클 제약 조건 변경 (생성, 추가, 삭제) (1) | 2024.02.16 |