WITH RECURSIVE
현재 내용은 ref. 2 에서 설명을 잘해 주고 있다. ref. 2 의 설명을 바탕으로 재구성했다.WITH RECURSIVE t(n) AS (
-- initial query
SELECT 1
UNION ALL
-- recursive query
SELECT n+1 FROM t
)
-- parent query(or outer query)
SELECT n FROM t LIMIT 100;
- WITH RECURSIVE 결과 = initial query 결과 UNION ALL recursive query 1 UNION ALL recursive query 2 UNION ALL recursive query 3 ...
Exit 조건
recursive 에는 언제나 빠져나오는 조건이 필요하다. 이 조건은 다음과 같다.- recursive query 의 결과 set 이 empty
예제
WITH RECURSIVE t(n) AS (
-- initial query
SELECT 1
UNION ALL
-- recursive query
SELECT n+1 FROM t
)
-- parent query(or outer query)
SELECT n FROM t LIMIT 100;
위의 query 로 한번 보여주면,처음 result 는
1 // SELECT 12번째 result 는
t = |n | +--+ |1 | +--+ 1+1 // SELECT n+1 FROM t3번째 result 는
t = |n | +--+ |2 | +--+ 2+1 // SELECT n+1 FROM t
Test tip
ref.1 에 있는 이야기인데, Test 할 때는 LIMIT 을 사용하면 LOOP 이 도는 query 여도 결과를 확인할 수 있다. 이것은 PostgreSQL 의 구현은 실제 parent query 에 의해 쓰여지는 row 수만큼 WITH query 의 row 들을 산정 하기 때문에 LIMIT 을 걸면 loop 을 돌지않게 된다.그런데 이것은 production(실사용) 에서는 사용하지 말라고 한다. 다른 시스템들은 다르게 돌 수 있고 parent query 에서 sort 나 join 등을 하게 되면 LIMIT 이 의미가 없어진다.
개인적인 TIP
WITH RECURSIVE func_name(param,...) AS ( ... )위같은 WITH RECURSIVE 에서 func_name 은 fn-1 이라고 생각하면 이해하기 쉬워진다.
아래같은 식은 아래의 식을 WITH RECURSIVE 로 나타냈다고 보면 된다.
- fn = fn-1 + 1
WITH RECURSIVE t(n) AS (
-- initial query
SELECT 1
UNION ALL
-- recursive query
SELECT n+1 FROM t
)
-- parent query(or outer query)
SELECT n FROM t LIMIT 100;
EXAMPLES
WITH RECURSIVE r(no, date, code, count, cash, ratio) AS (
SELECT 0::bigint, '2015-10-01'::date, 'A005380', 66::float, 9800000, 0.1
UNION ALL
SELECT t.no AS no, t.date, r.code,
( ((r.count*t.close_price + r.cash)*r.ratio)/t.close_price )::float as count,
r.cash, r.ratio
from (
SELECT row_number() OVER (PARTITION BY code ORDER BY date) AS no, *
FROM mfactors_stockprice
WHERE date >= '2015-10-01' AND date <= '2015-11-01'
AND code='A005380'
) AS t, r
WHERE t.no = r.no + 1
)
SELECT * FROM r ;

댓글 없음:
댓글 쓰기