1. 분석 함수(Analytic Function)
- 분석 함수란? - 
- 테이블의 행을 특정 그룹별로 그루핑하여 편리하게 함수를 적용하는 것
 
- Sample 데이터 생성 SQL 
-- 1. PRODUCT_GROUP 테이블 생성
CREATE TABLE PRODUCT_GROUP (
GROUP_ID SERIAL PRIMARY KEY,
GROUP_NAME VARCHAR (255) NOT NULL
);
-- 1.1 PRODUCT_GROUP 데이터 삽입
INSERT INTO PRODUCT_GROUP (GROUP_NAME)
VALUES
('Smartphone')
, ('Laptop')
, ('Tablet');
SELECT * FROM PRODUCT_GROUP
  
    
      |  | group_id | group_name | 
  
  
    
      | 0 | 1 | Smartphone | 
    
      | 1 | 2 | Laptop | 
    
      | 2 | 3 | Tablet | 
  
 
-- 2. PRODUCT 테이블 생성
CREATE TABLE PRODUCT (
PRODUCT_ID SERIAL PRIMARY KEY
, PRODUCT_NAME VARCHAR (255) NOT NULL
, PRICE DECIMAL (11, 2)
, GROUP_ID INT NOT NULL
, FOREIGN KEY (GROUP_ID)
REFERENCES PRODUCT_GROUP (GROUP_ID)
);
-- 2.1 PRODUCT 데이터 삽입
INSERT INTO PRODUCT (PRODUCT_NAME,
GROUP_ID,PRICE)
VALUES
('Microsoft Lumia', 1, 200)
, ('HTC One', 1, 400)
, ('Nexus', 1, 500)
, ('iPhone', 1, 900)
, ('HP Elite', 2, 1200)
, ('Lenovo Thinkpad', 2, 700)
, ('Sony VAIO', 2, 700)
, ('Dell Vostro', 2, 800)
, ('iPad', 3, 700)
, ('Kindle Fire', 3, 150)
, ('Samsung Galaxy Tab', 3, 200);
SELECT * FROM PRODUCT
  
    
      |  | product_id | product_name | price | group_id | 
  
  
    
      | 0 | 1 | Microsoft Lumia | 200 | 1 | 
    
      | 1 | 2 | HTC One | 400 | 1 | 
    
      | 2 | 3 | Nexus | 500 | 1 | 
    
      | 3 | 4 | iPhone | 900 | 1 | 
    
      | 4 | 5 | HP Elite | 1200 | 2 | 
    
      | 5 | 6 | Lenovo Thinkpad | 700 | 2 | 
    
      | 6 | 7 | Sony VAIO | 700 | 2 | 
    
      | 7 | 8 | Dell Vostro | 800 | 2 | 
    
      | 8 | 9 | iPad | 700 | 3 | 
    
      | 9 | 10 | Kindle Fire | 150 | 3 | 
    
      | 10 | 11 | Samsung Galaxy Tab | 200 | 3 | 
  
 
2. OVER절
- OVER절?
- GROUP BY의 한계를 개선하기 위해 나온 함수
- 집계 함수의 결과를 테이블에 바로 보여줌
 
SELECT *
      , COUNT(*) OVER()
FROM PRODUCT
  
    
      |  | product_id | product_name | price | group_id | count | 
  
  
    
      | 0 | 1 | Microsoft Lumia | 200 | 1 | 11 | 
    
      | 1 | 2 | HTC One | 400 | 1 | 11 | 
    
      | 2 | 3 | Nexus | 500 | 1 | 11 | 
    
      | 3 | 4 | iPhone | 900 | 1 | 11 | 
    
      | 4 | 5 | HP Elite | 1200 | 2 | 11 | 
    
      | 5 | 6 | Lenovo Thinkpad | 700 | 2 | 11 | 
    
      | 6 | 7 | Sony VAIO | 700 | 2 | 11 | 
    
      | 7 | 8 | Dell Vostro | 800 | 2 | 11 | 
    
      | 8 | 9 | iPad | 700 | 3 | 11 | 
    
      | 9 | 10 | Kindle Fire | 150 | 3 | 11 | 
    
      | 10 | 11 | Samsung Galaxy Tab | 200 | 3 | 11 | 
  
 
3. OVER ... PARTITION BY 절
- PARTITION BY 절?
- GROUP BY와 비슷한 기능으로 OVER절, 분석함수와 같이 사용
- 특정 칼럼으로 그룹핑 하여 앞의 집계 함수를 그룹별로 적용
 
SELECT
    A.PRODUCT_NAME
    , A.PRICE
    , B.GROUP_NAME
    , AVG (A.PRICE) OVER (PARTITION BY B.GROUP_NAME)
FROM
PRODUCT A
INNER JOIN PRODUCT_GROUP B
ON (A.GROUP_ID = B.GROUP_ID);
  
    
      |  | product_name | price | group_name | avg | 
  
  
    
      | 0 | HP Elite | 1200 | Laptop | 850 | 
    
      | 1 | Lenovo Thinkpad | 700 | Laptop | 850 | 
    
      | 2 | Sony VAIO | 700 | Laptop | 850 | 
    
      | 3 | Dell Vostro | 800 | Laptop | 850 | 
    
      | 4 | Microsoft Lumia | 200 | Smartphone | 500 | 
    
      | 5 | HTC One | 400 | Smartphone | 500 | 
    
      | 6 | Nexus | 500 | Smartphone | 500 | 
    
      | 7 | iPhone | 900 | Smartphone | 500 | 
    
      | 8 | iPad | 700 | Tablet | 350 | 
    
      | 9 | Kindle Fire | 150 | Tablet | 350 | 
    
      | 10 | Samsung Galaxy Tab | 200 | Tablet | 350 | 
  
 
4. ROW _NUMBER, RANK, DENSE_RANK 함수
- 그룹에서 특정 컬럼의 순위를 구하는 함수 - 
- 
| 함수명 | 내용 |  - 
| ROW_NUMBER | - 같은 순위면 중복 상관 없이 순서대로 순위 구함 - EX) 10,20,20,30 일 때 -> 순위 : 1,2,3,4
 |  - 
| RANK | - 같은 순위면 다음 순위로 건너뜀 - EX) 10,20,20,30 일 때 -> 순위 : 1,2,2,4
 |  - 
| DENSE_RANK | - 같은 순위면 다음 순위로 건너뛰지 않음 -EX) 10,20,20,30 일 때 -> 순위 : 1,1,2,3
 |  
 
- ROW_NUMBER 
SELECT
    A.PRODUCT_NAME
    , B.GROUP_NAME
    , A.PRICE
    , ROW_NUMBER () OVER ( PARTITION BY B.GROUP_NAME ORDER BY A.PRICE)
FROM PRODUCT A
INNER JOIN PRODUCT_GROUP B
ON (A.GROUP_ID = B.GROUP_ID);
  
    
      |  | product_name | group_name | price | row_number | 
  
  
    
      | 0 | Sony VAIO | Laptop | 700 | 1 | 
    
      | 1 | Lenovo Thinkpad | Laptop | 700 | 2 | 
    
      | 2 | Dell Vostro | Laptop | 800 | 3 | 
    
      | 3 | HP Elite | Laptop | 1200 | 4 | 
    
      | 4 | Microsoft Lumia | Smartphone | 200 | 1 | 
    
      | 5 | HTC One | Smartphone | 400 | 2 | 
    
      | 6 | Nexus | Smartphone | 500 | 3 | 
    
      | 7 | iPhone | Smartphone | 900 | 4 | 
    
      | 8 | Kindle Fire | Tablet | 150 | 1 | 
    
      | 9 | Samsung Galaxy Tab | Tablet | 200 | 2 | 
    
      | 10 | iPad | Tablet | 700 | 3 | 
  
 
SELECT
    A.PRODUCT_NAME
    , B.GROUP_NAME
    , A.PRICE
    , RANK () OVER ( PARTITION BY B.GROUP_NAME ORDER BY A.PRICE)
FROM PRODUCT A
INNER JOIN PRODUCT_GROUP B
ON (A.GROUP_ID = B.GROUP_ID);
  
    
      |  | product_name | group_name | price | rank | 
  
  
    
      | 0 | Sony VAIO | Laptop | 700 | 1 | 
    
      | 1 | Lenovo Thinkpad | Laptop | 700 | 1 | 
    
      | 2 | Dell Vostro | Laptop | 800 | 3 | 
    
      | 3 | HP Elite | Laptop | 1200 | 4 | 
    
      | 4 | Microsoft Lumia | Smartphone | 200 | 1 | 
    
      | 5 | HTC One | Smartphone | 400 | 2 | 
    
      | 6 | Nexus | Smartphone | 500 | 3 | 
    
      | 7 | iPhone | Smartphone | 900 | 4 | 
    
      | 8 | Kindle Fire | Tablet | 150 | 1 | 
    
      | 9 | Samsung Galaxy Tab | Tablet | 200 | 2 | 
    
      | 10 | iPad | Tablet | 700 | 3 | 
  
 
SELECT
    A.PRODUCT_NAME
    , B.GROUP_NAME
    , A.PRICE
    , DENSE_RANK () OVER ( PARTITION BY B.GROUP_NAME ORDER BY A.PRICE)
FROM PRODUCT A
INNER JOIN PRODUCT_GROUP B
ON (A.GROUP_ID = B.GROUP_ID);
  
    
      |  | product_name | group_name | price | dense_rank | 
  
  
    
      | 0 | Sony VAIO | Laptop | 700 | 1 | 
    
      | 1 | Lenovo Thinkpad | Laptop | 700 | 1 | 
    
      | 2 | Dell Vostro | Laptop | 800 | 2 | 
    
      | 3 | HP Elite | Laptop | 1200 | 3 | 
    
      | 4 | Microsoft Lumia | Smartphone | 200 | 1 | 
    
      | 5 | HTC One | Smartphone | 400 | 2 | 
    
      | 6 | Nexus | Smartphone | 500 | 3 | 
    
      | 7 | iPhone | Smartphone | 900 | 4 | 
    
      | 8 | Kindle Fire | Tablet | 150 | 1 | 
    
      | 9 | Samsung Galaxy Tab | Tablet | 200 | 2 | 
    
      | 10 | iPad | Tablet | 700 | 3 | 
  
 
5. FIRST _VALUE , LAST_VALUE 함수
SELECT
  A.PRODUCT_NAME, B.GROUP_NAME, A.PRICE
  , FIRST_VALUE (A.PRICE) over (
      PARTITION BY B.GROUP_NAME ORDER BY A.PRICE
      ) AS LOWEST_PRICE_PER_GROUP
FROM PRODUCT A
INNER JOIN PRODUCT_GROUP B
ON (A.GROUP_ID = B.GROUP_ID);
  
    
      |  | product_name | group_name | price | lowest_price_per_group | 
  
  
    
      | 0 | Sony VAIO | Laptop | 700 | 700 | 
    
      | 1 | Lenovo Thinkpad | Laptop | 700 | 700 | 
    
      | 2 | Dell Vostro | Laptop | 800 | 700 | 
    
      | 3 | HP Elite | Laptop | 1200 | 700 | 
    
      | 4 | Microsoft Lumia | Smartphone | 200 | 200 | 
    
      | 5 | HTC One | Smartphone | 400 | 200 | 
    
      | 6 | Nexus | Smartphone | 500 | 200 | 
    
      | 7 | iPhone | Smartphone | 900 | 200 | 
    
      | 8 | Kindle Fire | Tablet | 150 | 150 | 
    
      | 9 | Samsung Galaxy Tab | Tablet | 200 | 150 | 
    
      | 10 | iPad | Tablet | 700 | 150 | 
  
 
SELECT
  A.PRODUCT_NAME, B.GROUP_NAME, A.PRICE
  , LAST_VALUE (A.PRICE) OVER(
    PARTITION BY B.GROUP_NAME ORDER BY A.PRICE
    RANGE BETWEEN UNBOUNDED PRECEDING
    AND UNBOUNDED FOLLOWING
  ) AS HIGHEST_PRICE_PER_GROUP
FROM PRODUCT A
INNER JOIN PRODUCT_GROUP B
ON (A.GROUP_ID = B.GROUP_ID);
  
    
      |  | product_name | group_name | price | upper_price_per_group | 
  
  
    
      | 0 | Sony VAIO | Laptop | 700 | 1200 | 
    
      | 1 | Lenovo Thinkpad | Laptop | 700 | 1200 | 
    
      | 2 | Dell Vostro | Laptop | 800 | 1200 | 
    
      | 3 | HP Elite | Laptop | 1200 | 1200 | 
    
      | 4 | Microsoft Lumia | Smartphone | 200 | 900 | 
    
      | 5 | HTC One | Smartphone | 400 | 900 | 
    
      | 6 | Nexus | Smartphone | 500 | 900 | 
    
      | 7 | iPhone | Smartphone | 900 | 900 | 
    
      | 8 | Kindle Fire | Tablet | 150 | 700 | 
    
      | 9 | Samsung Galaxy Tab | Tablet | 200 | 700 | 
    
      | 10 | iPad | Tablet | 700 | 700 | 
  
 
6. LAG, LEAD 함수
- 그룹안에서 특정 컬럼의 이전 행 또는 다음 행 값을 구함
| 함수 | 내용 | 
| LAG | 이전 행의 값을 구함 | 
| LEAD | 다음행의 값을 구함 | 
SELECT A.PRODUCT_NAME, B.GROUP_NAME, A.PRICE
,             LAG (A.PRICE, 1) OVER (PARTITION BY B.GROUP_NAME ORDER BY A.PRICE ) AS PREV_PRICE
, A.PRICE - LAG (A.PRICE, 1) OVER (PARTITION BY B.GROUP_NAME ORDER BY A.PRICE ) AS CUR_PREV_DIFF
FROM PRODUCT A
INNER JOIN PRODUCT_GROUP B
ON (A.GROUP_ID = B.GROUP_ID);
  
    
      |  | product_name | group_name | price | prev_price | cur_prev_diff | 
  
  
    
      | 0 | Sony VAIO | Laptop | 700 | None | None | 
    
      | 1 | Lenovo Thinkpad | Laptop | 700 | 700.00 | 0.00 | 
    
      | 2 | Dell Vostro | Laptop | 800 | 700.00 | 100.00 | 
    
      | 3 | HP Elite | Laptop | 1200 | 800.00 | 400.00 | 
    
      | 4 | Microsoft Lumia | Smartphone | 200 | None | None | 
    
      | 5 | HTC One | Smartphone | 400 | 200.00 | 200.00 | 
    
      | 6 | Nexus | Smartphone | 500 | 400.00 | 100.00 | 
    
      | 7 | iPhone | Smartphone | 900 | 500.00 | 400.00 | 
    
      | 8 | Kindle Fire | Tablet | 150 | None | None | 
    
      | 9 | Samsung Galaxy Tab | Tablet | 200 | 150.00 | 50.00 | 
    
      | 10 | iPad | Tablet | 700 | 200.00 | 500.00 | 
  
 
SELECT A.PRODUCT_NAME, B.GROUP_NAME, A.PRICE
,             LEAD (A.PRICE, 1) OVER ( PARTITION BY B.GROUP_NAME ORDER BY A.PRICE ) AS NEXT_PRICE
, A.PRICE - LEAD (A.PRICE, 1) OVER ( PARTITION BY B.GROUP_NAME ORDER BY A.PRICE )AS CUR_NEXT_DIFF
FROM PRODUCT A
INNER JOIN PRODUCT_GROUP B
ON (A.GROUP_ID = B.GROUP_ID);
  
    
      |  | product_name | group_name | price | prev_price | cur_prev_diff | 
  
  
    
      | 0 | Sony VAIO | Laptop | 700 | 700.00 | 0.00 | 
    
      | 1 | Lenovo Thinkpad | Laptop | 700 | 800.00 | -100.00 | 
    
      | 2 | Dell Vostro | Laptop | 800 | 1200.00 | -400.00 | 
    
      | 3 | HP Elite | Laptop | 1200 | None | None | 
    
      | 4 | Microsoft Lumia | Smartphone | 200 | 400.00 | -200.00 | 
    
      | 5 | HTC One | Smartphone | 400 | 500.00 | -100.00 | 
    
      | 6 | Nexus | Smartphone | 500 | 900.00 | -400.00 | 
    
      | 7 | iPhone | Smartphone | 900 | None | None | 
    
      | 8 | Kindle Fire | Tablet | 150 | 200.00 | -50.00 | 
    
      | 9 | Samsung Galaxy Tab | Tablet | 200 | 700.00 | -500.00 | 
    
      | 10 | iPad | Tablet | 700 | None | None | 
  
 
# 참고