WITH BASE AS ( SELECT '401' CODE , '1' CODE_GROUP , '3' GRADE, '10' POINT , '20120201' INPUT_DATE FROM DUAL UNION ALL SELECT '402' CODE , '1' CODE_GROUP , '2' GRADE, '100' POINT , '20120301' INPUT_DATE FROM DUAL UNION ALL SELECT '403' CODE , '1' CODE_GROUP , '1' GRADE, '1000' POINT , '20120401' INPUT_DATE FROM DUAL UNION ALL SELECT '404' CODE , '1' CODE_GROUP , '1' GRADE, '1000' POINT , '20120501' INPUT_DATE FROM DUAL UNION ALL SELECT '405' CODE , '1' CODE_GROUP , '1' GRADE, '1000' POINT , '20120601' INPUT_DATE FROM DUAL UNION ALL SELECT '407' CODE , '2' CODE_GROUP , '3' GRADE, '10' POINT , '20120101' INPUT_DATE FROM DUAL UNION ALL SELECT '408' CODE , '2' CODE_GROUP , '2' GRADE, '100' POINT , '20120201' INPUT_DATE FROM DUAL UNION ALL SELECT '409' CODE , '2' CODE_GROUP , '1' GRADE, '1000' POINT , '20120301' INPUT_DATE FROM DUAL UNION ALL SELECT '410' CODE , '3' CODE_GROUP , '1' GRADE, '1000' POINT , '20120201' INPUT_DATE FROM DUAL UNION ALL SELECT '411' CODE , '3' CODE_GROUP , '2' GRADE, '100' POINT , '20120301' INPUT_DATE FROM DUAL )SELECT * FROM BASE ;
WITH RESULT1 AS ( SELECT '1' CODE_GROUP , '1110' SUM_POINT FROM DUAL UNION ALL SELECT '2' CODE_GROUP , '1110' SUM_POINT FROM DUAL UNION ALL SELECT '3' CODE_GROUP , '1000' SUM_POINT FROM DUAL )SELECT * FROM RESULT1 ;
WITH RESULT_FINAL AS ( SELECT '1' CODE_GROUP , '1110' SUM_POINT FROM DUAL UNION ALL SELECT '2' CODE_GROUP , '1110' SUM_POINT FROM DUAL UNION ALL SELECT '3' CODE_GROUP , '1000' SUM_POINT FROM DUAL )SELECT SUM(SUM_POINT) FROM RESULT_FINAL ;
--근데 위에 최종 결과가 3220인데, 3320이 정답 아닌가요? --CODE_GROUP 3를 보면, 서로 다른 등급 GRADE (1, 2) 2개 있습니다. 2개 더하면 1100입니다. --근데 중간 결과에 1000으로 되어 있네요. --단서를 보면 1000이 맞다고 되어 있는데, 이게 code_group 기준으로 grade가 높은 등급이 있어 --2번째 등급을 취하지 않는다는 것인데 이런 기준으로 본다면 다른 code_group도 높은 1등급이 있으니 --2등급, 3등급 데이타를 취하지 않아야 할 것 같은데.... (난독증 + 머리나쁨... ㅠㅠ) SELECT SUM(POINT) POINT FROM ( SELECT CODE_GROUP, GRADE, POINT FROM BASE GROUP BY CODE_GROUP, GRADE, POINT );
아... 이해 했습니다.
날짜가 대한 언급이 없는 것 같아 아예 날짜를 배제 시켰는데
역추하면 INPUT_DATE 날짜로 차이가 발생하네요... 뉴ㅅ뉴)ㆀ
물론 아래 분들의 답을 보고 이해... OTL
WITH BASE AS ( SELECT '401' CODE , '1' CODE_GROUP , '3' GRADE, '10' POINT , '20120201' INPUT_DATE FROM DUAL UNION ALL SELECT '402' CODE , '1' CODE_GROUP , '2' GRADE, '100' POINT , '20120301' INPUT_DATE FROM DUAL UNION ALL SELECT '403' CODE , '1' CODE_GROUP , '1' GRADE, '1000' POINT , '20120401' INPUT_DATE FROM DUAL UNION ALL SELECT '404' CODE , '1' CODE_GROUP , '1' GRADE, '1000' POINT , '20120501' INPUT_DATE FROM DUAL UNION ALL SELECT '405' CODE , '1' CODE_GROUP , '1' GRADE, '1000' POINT , '20120601' INPUT_DATE FROM DUAL UNION ALL SELECT '407' CODE , '2' CODE_GROUP , '3' GRADE, '10' POINT , '20120101' INPUT_DATE FROM DUAL UNION ALL SELECT '408' CODE , '2' CODE_GROUP , '2' GRADE, '100' POINT , '20120201' INPUT_DATE FROM DUAL UNION ALL SELECT '409' CODE , '2' CODE_GROUP , '1' GRADE, '1000' POINT , '20120301' INPUT_DATE FROM DUAL UNION ALL SELECT '410' CODE , '3' CODE_GROUP , '1' GRADE, '1000' POINT , '20120201' INPUT_DATE FROM DUAL UNION ALL SELECT '411' CODE , '3' CODE_GROUP , '2' GRADE, '100' POINT , '20120301' INPUT_DATE FROM DUAL ) SELECT CODE_GROUP , SUM(CASE WHEN GRADE <= MIN_GRADE THEN POINT END ) PT FROM (SELECT DISTINCT MIN(GRADE) OVER(PARTITION BY CODE_GROUP ORDER BY CODE) MIN_GRADE ,CODE_GROUP , GRADE , POINT FROM BASE ) GROUP BY ROLLUP (CODE_GROUP) ORDER BY CODE_GROUP
SELECT DISTINCT MIN(GRADE) OVER(PARTITION BY CODE_GROUP ORDER BY INPUT_DATE) MIN_GRADE
SELECT SUM(point) sum_point
FROM (SELECT grade
, point
, LAG(grade, 1, '9') OVER(PARTITION BY code_group ORDER BY input_date) lag_grade
FROM base
)
WHERE grade < lag_grade
;
-- 상승 > 하락 > 상승을 반복하는 경우 등급향상 단 한번만 인정한다면 다음과 같이 --
SELECT SUM(MAX(point)) sum_point
FROM (SELECT code_group, grade, point
, LAG(grade, 1, '9') OVER(PARTITION BY code_group ORDER BY input_date) lag_grade
FROM base
)
WHERE grade < lag_grade
GROUP BY code_group, grade
;