|
我写的:
最小公倍数:
WITH n AS (
SELECT 4 n FROM DUAL
UNION ALL SELECT 9 FROM DUAL
UNION ALL SELECT 6 FROM DUAL
UNION ALL SELECT 15 FROM DUAL
)
,n2 AS (SELECT ROWNUM id,COUNT(*) OVER() cnt,n FROM n)
,t (id,cnt,val,a,b,lcm) AS (
SELECT id,cnt,n,0,1,n FROM n2 WHERE id=1
UNION ALL
SELECT DECODE(t.a,0,t.id+1,t.id)
,t.cnt
,n2.n
,DECODE(t.a,0,n2.n,MOD(t.b,t.a))
,DECODE(t.a,0,t.lcm,t.a)
END
,DECODE(mod(t.b,t.a),0,t.lcm*t.val/t.a,t.lcm)
FROM t,n2
WHERE (t.id<t.cnt OR t.id=t.cnt AND t.a<>0)
AND DECODE(t.a,0,t.id+1,t.id) = n2.id
)
SELECT lcm FROM t WHERE a=0 AND id=cnt;
LCM
----------
180
最大公约数:
WITH n AS (
SELECT 20 n FROM DUAL
UNION ALL SELECT 16 FROM DUAL
UNION ALL SELECT 18 FROM DUAL
UNION ALL SELECT 12 FROM DUAL
)
,n2 AS (SELECT ROWNUM id,COUNT(*) OVER() cnt,n FROM n)
,t (id,cnt,val,a,b,gcd) AS (
SELECT id,cnt,n,0,1,n FROM n2 WHERE id=1
UNION ALL
SELECT DECODE(t.a,0,t.id+1,t.id)
,t.cnt
,n2.n
,DECODE(t.a,0,n2.n,MOD(t.b,t.a))
,DECODE(t.a,0,t.gcd,t.a)
,DECODE(mod(t.b,t.a),0,t.a,t.gcd)
FROM t,n2
WHERE (t.id<t.cnt OR t.id=t.cnt AND t.a<>0)
AND DECODE(t.a,0,t.id+1,t.id) = n2.id
)
SELECT gcd FROM t WHERE a=0 AND id=cnt;
GCD
----------
2
如果是连续自然数则集合n可以忽略,下面是1~1E6的GCD:
WITH t (id,a,b,gcd) AS (
SELECT 1,0,1,1 FROM DUAL
UNION ALL
SELECT DECODE(t.a,0,t.id+1,t.id)
,DECODE(t.a,0,t.id+1,MOD(t.b,t.a))
,DECODE(t.a,0,t.gcd,t.a)
,DECODE(mod(t.b,t.a),0,t.a,t.gcd)
FROM t
WHERE (t.id<1E6 OR t.id=1E6 AND t.a<>0)
)
SELECT gcd FROM t WHERE a=0 AND id=1E6;
GCD
----------
1
Elapsed: 00:01:43.66
当然这没什么意思。
我在新出的书中有一章专门写这个递归WITH(包括那个斐波那契数), 另外还有很多例子散落在论坛的回帖中。
[ 本帖最后由 newkid 于 2010-12-11 03:59 编辑 ] |
|