행으로 표현된 데이터 값 열로 표현하는 쿼리 방법은? 0 10 2,667

by 권사마 [SQL Query] [2023.04.04 11:03:51]


조회 데이터에 대한 문의입니다.
아래 보시는 "데이터"를 아래 보이는 "To-BE) 조회값" 처럼 쿼리를 생성하고 싶습니다.
행으로 표현된 금액값을 열로 표현하려면 어떻게 해야 좋을까요? ^^

* 데이터
SELECT '1'   AS cnt,
       '01'  AS code,
       '100' AS amt
FROM DUAL
UNION ALL
SELECT '1'   AS cnt,
       '02'  AS code,
       '200' AS amt
FROM DUAL
UNION ALL
SELECT '1'   AS cnt,
       '03'  AS code,
       '300' AS amt
FROM DUAL
UNION ALL
SELECT '2'   AS cnt,
       '01'  AS code,
        '10' AS amt
FROM DUAL
UNION ALL
SELECT '2'   AS cnt,
       '02'  AS code,
       '20'  AS amt
FROM DUAL
UNION ALL
SELECT '2'   AS cnt,
       '03'  AS code,
       '30'  AS amt
FROM DUAL     
;

* AS-IS) 조회값

cnt code amt
1 01 100
1 02 200
1 03 300
2 01 10
2 02 20
2 03 30

* To-BE) 조회값

amt1 amt2 amt3
100 200 300
10 20 30

 

by 동동동 [2023.04.04 11:11:04]

cnt 기준으로 3개씩 끊는 건가요? 아니면 그냥 row별로 3개씩인가요?

예) cnt가 6다음에 7이 아니라 8이라면 amt1은 null이고 amt2에 cnt 8의 값이 나와야 하나요?


by 권사마 [2023.04.04 11:46:37]

1. code(01~03)별로 3개씩 끊는거라고 보시면 될것 같습니다.


by 마농 [2023.04.04 11:17:08]

cnt 나 amt 는 문자 아니고 숫자일 듯 한데요? 따옴표 없는게 맞겠죠?
code 값이 쿼리의 값(01~03 2회 반복)과 조회값(01~06)이 다른데요? 뭐가 맞는지?
cnt 는 원래 있던 값인가요? 만들어낸 값인가요? (정렬 결과 순번?)

나누는 기준이 명확하지 않네요?
- cnt인지? ROWNUM 인지? code 인지?
- cnt 는 어떤 의미의 항목인지?
- 제시되지는 않았지만 정렬 기준 항목이 따로 있는 것은 아닌지?


by 권사마 [2023.04.04 11:46:46]

1. cnt는  rownum 이라고 보시면 될것 같습니다.
2. cnt는 순번이라고 보시면 될것 같습니다. 
3. 정렬기준은 따로 없습니다.
4. code 값이 쿼리의 값(01~03 2회 반복)과 조회값(01~06)이 다른데요? 뭐가 맞는지?
   --> 조회값(01~03)은 본문에 수정하였습니다. 오타가 있었네요 ^^


by 마농 [2023.04.04 12:32:55]

그냥 단순 로넘이라고 할 수는 없습니다.
첫 세줄과 다음 세줄을 나누는 기준이 필요합니다.
테이블에 위 예시처럼 데이터가 순서대로 이쁘게 들어가 있으리라는 보장이 없습니다.
테이블의 데이터는 뒤죽박죽 들어 있습니다.
뭔가 정렬 기준이라든가 그룹 기준이 필요합니다.
위 예시에서. 테이블 자료의 순서가 뒤섞여 있다고 가정했을 때.
(100, 200, 300)을 하나의 그룹으로 묶고
(10, 20, 30)을 하나의 그룹으로 묶은 이유가 있을 것입니다.
그 이유를, 근거를 보여주셔야 합니다.
rownum 은 근거가 될 수 없습니다.


by 권사마 [2023.04.04 17:42:46]

첫 세줄과 다음 세줄을 나누는 기준이 필요합니다.

--> CNT 값과 CODE 컬럼의 값이 세줄을 나누는 기준이 될것 같습니다.

      1. CNT 값이 1,2 이렇게 두개의 그룹이 되고,

      2. CODE 컬럼의 값이 "01~03" 고정값입니다. 

        세줄로 나누는 기준이 CODE 컬럼의 고정된 3개의 값으로 나누는 기준이 될것 같습니다.

* 본분의 조회값이 잘못예시를 든것 같아 수정하였습니다. (CNT 컬럼 수정)


by 동동동 [2023.04.04 14:15:59]

마농님 말씀처럼 묶이는 명확한 근거가 있어야 하겠지만...

일단 무조건 3 Row씩 자른다면...다음과 같이 해보았습니다.

WITH TMP AS (
SELECT '1'   AS cnt, '01'  AS code, '100' AS amt FROM DUAL UNION ALL
SELECT '2'   AS cnt, '02'  AS code, '200' AS amt FROM DUAL UNION ALL
SELECT '3'   AS cnt, '03'  AS code, '300' AS amt FROM DUAL UNION ALL
SELECT '4'   AS cnt, '01'  AS code, '10'  AS amt FROM DUAL UNION ALL
SELECT '5'   AS cnt, '02'  AS code, '20'  AS amt FROM DUAL UNION ALL
SELECT '6'   AS cnt, '03'  AS code, '30'  AS amt FROM DUAL UNION ALL
SELECT '8'   AS cnt, '01'  AS code, '15'  AS amt FROM DUAL UNION ALL
SELECT '9'   AS cnt, '02'  AS code, '25'  AS amt FROM DUAL UNION ALL
SELECT '11'  AS cnt, '03'  AS code, '35'  AS amt FROM DUAL
)
SELECT *
  FROM (SELECT TRUNC((ROWNUM-1)/ 3) GUBUN, code, amt FROM TMP)
  PIVOT(SUM(amt) FOR code IN('01' AS AMT1, '02' AS AMT2, '03' AS AMT3))
ORDER BY GUBUN
;

 


by 권사마 [2023.04.05 09:00:02]

감사합니다 ^^ 많은 도움이 되었습니다 ^^


by 마농 [2023.04.04 18:01:18]

애초에 예시를 잘 못 들어서 일어난 일이네요.
그룹 기준이 명확하게 있었네요.
 

WITH t AS
(
SELECT 1 cnt, '01' code, 100 amt FROM dual
UNION ALL SELECT 1, '02', 200 FROM dual
UNION ALL SELECT 1, '03', 300 FROM dual
UNION ALL SELECT 2, '01',  10 FROM dual
UNION ALL SELECT 2, '02',  20 FROM dual
UNION ALL SELECT 2, '03',  30 FROM dual
)
SELECT *
  FROM t
 PIVOT (MIN(amt) FOR code IN ('01' amt1, '02' amt2, '03' amt3))
;

 


by 권사마 [2023.04.05 08:59:48]

감사합니다 ^^ 많은 도움이 되었습니다 ^^

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