피벗관련 질문드려요. 0 1 4,613

by 바라기짱조아 [SQL Query] [2024.11.18 21:12:35]


안녕하세요, 쿼리 작성중 막혀 질문드립니다. ㅠㅠ

아래와 같은 데이터가 기준년월 월평균 4000-5000건 정도존재합니다.

회원명

성별

가입일자

포인트

홍길동

2024.05.01

 10000

김길동

2024.01.01

 20000

이길동

2024.01.05

 1000

김선희

2024.01.07

 5600

이서방

2024.01.11

5600

김효리

2024.05.01

5600

아래와 같이 데이터를 처리하고 싶은데 피벗함수가 있더라구요.

가로는 회원명(가변) - 해당 년월에 따라 가변적인 데이터(중복 제거)

세로는 성별,가입일자,포인트 는 고정항목

 

홍길동

김길동

이길동

김선희

이서방

김효리

.......

.......

.....

.....

성별

남 

 남

 여

 남

 여

.....

..... 

..... 

... 

.... 

가입일자

2024.05.01

2024.01.01

2024.01.05

 

2024.01.07

2024.01.11

 

2024.05.01

 

....

....

....

....

...

포인트

10000

20000

1000

5600

5600

5600

...

...

...

..

...

이런식으로 옆으로 동적 결과가 나오게 하고싶습니다.

어떻게 해야할지 막막한데 해결방법이 없을까요?

고수님들 부탁드려봅니다.

WITH T AS

(

SELECT 'MAN1' 회원명, 'M' 성별, '4000' 포인트, '20180101' 가입일자 FROM DUAL

UNION ALL SELECT 'MAN2', 'M', '1000', '20240102' FROM DUAL

UNION ALL SELECT 'MAN3', 'M', '2000', '20240103' FROM DUAL

UNION ALL SELECT 'MAN4', 'M', '4000', '20240104' FROM DUAL

UNION ALL SELECT 'MAN5', 'M', '4000', '20240105' FROM DUAL

UNION ALL SELECT 'MAN6', 'M', '1000', '20240106' FROM DUAL

UNION ALL SELECT 'MAN7', 'W', '2000', '20240107' FROM DUAL

UNION ALL SELECT 'MAN8', 'M', '3000', '20240108' FROM DUAL

UNION ALL SELECT 'MAN9', 'M', '3000', '20240109' FROM DUAL

UNION ALL SELECT 'MA10', 'M', '3000', '20240109' FROM DUAL

)

SELECT *

FROM T

by 마농 [2024.11.19 08:35:05]

피벗 쿼리는 값의 개수와 각각의 값을 이미 알고 있어야 정적쿼리로 가능합니다.
가변적인 값과 가변적인 개수에 대해서는 동적 쿼리를 사용해야 합니다.
 

WITH t AS
(
SELECT 'MAN1' 회원명, 'M' 성별, 4000 포인트, '20180101' 가입일자 FROM dual
UNION ALL SELECT 'MAN2', 'M', 1000, '20240102' FROM dual
UNION ALL SELECT 'MAN3', 'M', 2000, '20240103' FROM dual
UNION ALL SELECT 'MAN4', 'M', 4000, '20240104' FROM dual
UNION ALL SELECT 'MAN5', 'M', 4000, '20240105' FROM dual
UNION ALL SELECT 'MAN6', 'M', 1000, '20240106' FROM dual
UNION ALL SELECT 'MAN7', 'W', 2000, '20240107' FROM dual
UNION ALL SELECT 'MAN8', 'M', 3000, '20240108' FROM dual
UNION ALL SELECT 'MAN9', 'M', 3000, '20240109' FROM dual
UNION ALL SELECT 'MA10', 'M', 3000, '20240109' FROM dual
)
-- 다음 쿼리를 동적으로 구현하셔야 합니다 --
SELECT *
  FROM (SELECT 회원명, 성별, 가입일자
             , TO_CHAR(포인트) 포인트    -- 자료형 일치
          FROM t
        )
 UNPIVOT(v FOR 구분 IN (성별, 가입일자, 포인트))
 PIVOT(MIN(v) FOR 회원명 IN ( 'MAN1' MAN1
                            , 'MAN2' MAN2
                            , 'MAN3' MAN3
                            , 'MAN4' MAN4
                            , 'MAN5' MAN5
                            , 'MAN6' MAN6
                            , 'MAN7' MAN7
                            , 'MAN8' MAN8
                            , 'MAN9' MAN9
                            , 'MA10' MA10
                            ) )
 ORDER BY INSTR('성별, 가입일자, 포인트', 구분)
;
WITH t AS
(
SELECT 'MAN1' 회원명, 'M' 성별, 4000 포인트, '20180101' 가입일자 FROM dual
UNION ALL SELECT 'MAN2', 'M', 1000, '20240102' FROM dual
UNION ALL SELECT 'MAN3', 'M', 2000, '20240103' FROM dual
UNION ALL SELECT 'MAN4', 'M', 4000, '20240104' FROM dual
UNION ALL SELECT 'MAN5', 'M', 4000, '20240105' FROM dual
UNION ALL SELECT 'MAN6', 'M', 1000, '20240106' FROM dual
UNION ALL SELECT 'MAN7', 'W', 2000, '20240107' FROM dual
UNION ALL SELECT 'MAN8', 'M', 3000, '20240108' FROM dual
UNION ALL SELECT 'MAN9', 'M', 3000, '20240109' FROM dual
UNION ALL SELECT 'MA10', 'M', 3000, '20240109' FROM dual
)
-- 최대 개수를 정해서 정적쿼리로 구현하는 방안 --
SELECT *
  FROM (SELECT 회원명, 성별, 가입일자
             , TO_CHAR(포인트) 포인트    -- 자료형 일치
             , ROW_NUMBER() OVER(ORDER BY 회원명) rn  -- 피벗용 순번
          FROM t
        )
 UNPIVOT(v FOR 구분 IN (회원명, 성별, 가입일자, 포인트))
 PIVOT(MIN(v) FOR rn IN (  1,  2,  3,  4,  5,  6,  7,  8,  9, 10
                        , 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
                        ) )
 ORDER BY INSTR('회원명, 성별, 가입일자, 포인트', 구분)
;

 

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입