|
lastwinner 发表于 2014-3-10 04:04 ![]()
8、分段求解
虽然sql没法像pl/sql那样有效的利用之前的计算结果,但部分做到还是可行的吧?我们来尝试一下 ...
但newkid的写法不能使用此思路,想想看为什么?
如果没想出来,那么看看如下的sql,其中 :n 赋值为400000,看看输出结果,就能大概想明白了
with b as (select 1 r from dual union all select 2 from dual),
c as (select rownum from b,b,b,b,b),
d as (select rownum from c,c,c,c),
e as (select rownum rn from d), --只需要一半
t0 AS (
SELECT 2*rn+1 rn FROM e where rn <= (:n)/2-1 --原SQL为(:n)/2-1-1有误,特做此更正——by lastwinner
),
t1 as(SELECT rn from t0 where mod(rn,3)<>0 and mod(rn,5)<>0 and mod(rn,7)<>0 and mod(rn,11)<>0 and mod(rn,13)<>0 and mod(rn,17)<>0 and mod(rn,19)<>0),
u1 as (select rn from t1 where rn<=sqrt(:n)),
u2 as (select rn from t1 where rn>sqrt(:n) and rn<=:n),
v1 as (SELECT rn from u1
MINUS
SELECT t1.rn * t2.rn
FROM u1 t1, u1 t2
WHERE t1.rn <= t2.rn
AND t1.rn BETWEEN 21 AND sqrt(SQRT(:n))+1
AND t1.rn * t2.rn <=sqrt(:n)+1),
u3 as (select * from u2 union select * from v1),
v2 as (SELECT rn from u2
MINUS
SELECT t1.rn * t2.rn
FROM v1 t1, u3 t2
WHERE t1.rn <= t2.rn
AND t1.rn BETWEEN 21 AND SQRT(:n)
AND
t1.rn * t2.rn <=:n)
, u as (select rn n from t1)
, z as (select * from u minus
select * from u a where exists (select /*+ USE_MERGE (a b)*/ 0 from u b where b.n<=sqrt(a.n) and mod(a.n, b.n)=0))
select * from v2 minus select * from z
/ |
|