|
原帖由 tree_new_bee 于 2010-12-23 12:41 发表 ![]()
想不出找边界的办法, 只好逐步试。
试到1000000, 得到了11个数。
实现很容易, 基本上把Q35稍稍修改就行。
with tprim as (select /*+ RESULT_CACHE */ column_value prim from table(pkg_prim2.seive_numlist(1000000))
where column_value>10 and translate(substr(column_value,2), '$1379','$') is null
and substr(column_value,1,1) in ('2','3','5','7') and substr(column_value,-1,1) in ('3', '7')
)
--select * from tprim
,tpos as (select rownum pos from dual connect by rownum0
))
COUNT(PRIM) SUM(PRIM)--SELECT*
----------- ------------------
11 748317
Executed in 0.141 seconds
别说, 还挺快。
这11个数是:
PRIM
----------
23
37
53
73
313
317
373
797
3137
3797
739397
11 rows selected
我用你的思路改写的纯SQL,不知错在哪里
with ta as
(select level*2+1 l from dual connect by level<=sqrt(:N)/2),
t1 as (select level*2+1 l from dual connect by level<=sqrt(:N)/3)
,p1k as(select l rn from ta --1000以内的质数
minus
select t1.l*t2.l from t1,t1 t2 where t1.l<=sqrt(sqrt(:N))
and t1.l<=t2.l and t1.l*t2.l<=:N
)
,t0 AS (
SELECT 6*ROWNUM+1 rn FROM DUAL CONNECT BY ROWNUM <= (:n)/6
union all
SELECT 6*ROWNUM+5 rn FROM DUAL CONNECT BY ROWNUM <= (:n)/6
),
t as(SELECT rn from t0
where 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
and mod(rn,23)<>0
and mod(rn,29)<>0
)
,tnew as(SELECT rn from t
MINUS
SELECT /*+ USE_MERGE (t1 t2) */ t1.rn * t2.rn
FROM p1k t1, t t2
WHERE t1.rn <= t2.rn
AND t1.rn BETWEEN 31 AND (SELECT SQRT(:n) FROM DUAL)
AND t1.rn * t2.rn <:n and t2.rn<=:n/31
union select * from p1k where rn<31
),
tprim as (select rn prim from tnew
where rn>10 and translate(substr(rn,2), '$1379','$') is null
and substr(rn,1,1) in ('2','3','5','7') and substr(rn,-1,1) in ('3', '7')
)
--select * from tprim where
,tpos as (select rownum pos from dual connect by rownum<=6)
select count(*) from tprim
where not exists
(select 1 from p1k,tpos where pos<length(rn)
and (mod(substr(tprim.prim,pos+1),p1k.rn) =0
or mod(substr(tprim.prim,1, pos),p1k.rn)=0
))
/
NT(*)
-----
135 |
|