안녕하세요
쿼리에 대해 잘 몰라서 약 2주가량 구글링 해봐도 문제에 답을 찾지 못하여 여기에 문의 드립니다.
현재 업무에서 사용하는 DB는 verticadb 이고 oracle의 대부분의 쿼리가 동작합니다.
다만 약간의 기능 차이와 connect by, pivot 등의 함수는 동작하지 않아 가능한 ansi표준으로 부탁드립니다.
[수식]
NO | Q | T | V | W |
1 | 고정값 | 고정값 | Q1 - W1 | T1 * 01 |
2 | 고정값 | T1 - V1 | Q2 - W2 | T2 * 0.1 |
3 | 고정값 | T2 - V2 | Q3 - W3 | T3 * 0.1 |
4 | 고정값 | T3 - V3 | Q4 - W4 | T4 * 0.1 |
* 고정값 : 특정 값이 들어 있습니다.
* T1 형식의 의미는 T열의 1 Row의 값을 의미합니다.
* W열은 소수점 무시하면 됩니다.
[데이터]
Q | T | V | W | |
1 | 100 | 200 | 80 | 20 |
2 | 100 | 120 | 88 | 12 |
3 | 100 | 32 | 97 | 3 |
와 같은 형식으로 계산됩니다.
대상은 총 60만건 이고 대상당 60개의 row가 계산으로 생성되어야 합니다.
recursive를 이용하여 계산하는 쿼리를 작성했으나 verticadb는 recusive를 사용할때 최대 9개로 제한되어 있으며 제한을 60으로 변경하면 메모리 부족 오류가 발생됩니다.
첫번째 row와 2 ~ 60 row를 구할때 쿼리를 분리 해도 상관없습니다.
읽어 주셔서 감사합니다.
-- Oracle Recursive -- WITH t0 AS ( SELECT 1 id, 100 q, 200 t FROM dual UNION ALL SELECT 2, 200, 400 FROM dual ) , t1(id, no, q, t, v, w) AS ( SELECT id , 1 no , q , t , q - FLOOR(t * 0.1) v , FLOOR(t * 0.1) w FROM t0 UNION ALL SELECT id , no + 1 no , q , t - v t , q - FLOOR((t - v) * 0.1) v , FLOOR((t - v) * 0.1) w FROM t1 WHERE no < 3 -- 60 ) SELECT * FROM t1 ORDER BY id, no ;
vertica db에서 실행 해보았습니다.
recursive 방식을 사용하신것 같아서 기본 설정으로 실행 했을때는 정상이였으나
(vertica db 는 WithClauseRecursionLimit parameter값이 9로 설정되 있습니다.)
설정과 조건을 60으로 변경 하고 실행 해보니 아래와 같은 오류가 발생되었습니다.
Total allocated memory (MiB) = 1024 is about to exceed limit imposed by MaxParsedQuerySizeMB (MiB) ...
MaxParsedQuerySizeMB 설정 변경 요청을 해야 하는데 가능할지 걱정되네요.
다시한번 답변 감사합니다.
CREATE OR REPLACE FUNCTION f_test4 ( v_n NUMBER , v_q NUMBER , v_t NUMBER ) RETURN VARCHAR2 IS q NUMBER := v_q; t NUMBER := v_t; v NUMBER := 0; w NUMBER; v_rtn VARCHAR2(200); BEGIN FOR n IN 1..v_n LOOP t := t - v; w := FLOOR(t * 0.1); v := q - w; END LOOP; v_rtn := t ||','|| v ||','|| w; RETURN v_rtn; END; / WITH t0 AS ( SELECT 1 id, 100 q, 200 t FROM dual UNION ALL SELECT 2, 200, 400 FROM dual ) , copy_t AS ( SELECT LEVEL no FROM dual CONNECT BY LEVEL <= 4 --60 ) SELECT id , no , q , REGEXP_SUBSTR(x, '[^,]+', 1, 1) t , REGEXP_SUBSTR(x, '[^,]+', 1, 2) v , REGEXP_SUBSTR(x, '[^,]+', 1, 3) w FROM (SELECT id, no, q, t , f_test4(no, q, t) x FROM t0 , copy_t ) a ORDER BY id, no ;
혹시 저와 비슷한 상황을 경우가 있을것 같아 함수로 테스트한 결과 댓글로 남깁니다. ^^
verticadb에서 function 사용시 FOR문을 사용할수 없고 단순히 계산 로직만 넣을수 있네요
(https://www.vertica.com/docs/9.3.x/HTML/Content/Authoring/SQLReferenceManual/Statements/CREATEFUNCTIONSQLFunctions.htm
http://vertica-forums.com/viewtopic.php?t=786)
마농님께서 좋은 해결책을 알려주셨는데 verticadb에서는 사용할수 없어 60번 쿼리를 실행하는 방식으로 했습니다. ^^;;;;
다시한번 마농님과 제글을 읽어주신분께 감사드립니다.