oracle质数怎么算,借花献佛之使用Oracle sql求质数(笔记)
首先聲明一點(diǎn),文章內(nèi)容從itpub論壇上看到的,原文鏈接外鏈網(wǎng)址已屏蔽,本文主要是記錄下筆記,原文中有更詳細(xì)的分析。使用sql求質(zhì)素沒(méi)什么實(shí)用價(jià)值,重要的是思路。
(一)最簡(jiǎn)單的方法
思路:將2和所有大于等于3小于XX的奇數(shù)取出來(lái),做一中間結(jié)果集t。然后逐一校驗(yàn)t中的每個(gè)N是否是質(zhì)數(shù)。如果發(fā)現(xiàn)一個(gè)數(shù)字N不能被其他所有數(shù)字整除——當(dāng)然,這些數(shù)字要小于等于SQRT(N),那么N就是質(zhì)數(shù)
with t as(select 2 n from dual union select rownum*2+1 from dual connect by rownum<=(10000-2)/2)
select count(*) from t a where not exists (select null from t b where b.n<=sqrt(a.n) and mod(a.n, b.n)=0)
最直接的方法,可惜速度最慢。
(二)篩選法
思路:將從2到XX的數(shù)都列出來(lái),作為一個(gè)全集,然后減去所有的合數(shù),即可得到素?cái)?shù)集合
WITH t AS (
SELECT ROWNUM+1 rn FROM DUAL CONNECT BY ROWNUM <= 10000-1)
SELECT COUNT(*)
FROM (SELECT rn
from t
MINUS
SELECT t1.rn * t2.rn--4=2*2 2*3 9=3*3 3*4 16=4*4 4*5
FROM t t1, t t2
WHERE t1.rn <= t2.rn
AND t1.rn <= (SELECT SQRT(10000) FROM DUAL))
(三)改進(jìn)的篩選法
思路:除了2之外的偶數(shù),可以從全集和合數(shù)集中排除
WITH t AS (
--2-10000/2
SELECT ROWNUM+1 rn FROM DUAL CONNECT BY ROWNUM <= 10000/2-1
)
,t_odd AS (
--奇數(shù)
SELECT 2*ROWNUM+1 rn FROM DUAL CONNECT BY ROWNUM <= 10000/2-1
)
SELECT COUNT(*) + 1--+2
FROM (SELECT rn
from t_odd
MINUS
SELECT t1.rn * t2.rn
FROM t t1, t t2
WHERE t1.rn <= t2.rn
AND t1.rn <= (SELECT SQRT(10000) FROM DUAL)
AND t1.rn * t2.rn < 10000)
另一種寫(xiě)法:排除偶數(shù)
WITH t_odd AS (
SELECT 2*ROWNUM+1 rn FROM DUAL CONNECT BY ROWNUM <= 10000/2-1
)
SELECT COUNT(*) + 1
FROM (SELECT rn
from t_odd
MINUS
SELECT t1.rn * t2.rn --9=3*3 3*5 25=5*5 5*7 49=7*7
FROM t_odd t1, t_odd t2
WHERE t1.rn <= t2.rn
AND t1.rn <= (SELECT SQRT(10000) FROM DUAL)
AND t1.rn * t2.rn < 10000)
(四)逆向exists
with t as(select 2 n from dual union select rownum*2+1 from dual connect by rownum<=(10000-2)/2)
, z as (select * from t minus
select * from t a where exists (select null from t b where b.n<=sqrt(a.n) and mod(a.n, b.n)=0))
select count(*) from z
或者:
with t as(select rownum*2+1 n from dual connect by rownum<=(10000-2)/2
union select 3 from dual --F5執(zhí)行計(jì)劃 走M(jìn)ERGE JOIN
),z as (select * from t minus
select * from t a where exists (select null from t b where b.n<=sqrt(a.n) and mod(a.n, b.n)=0))
select count(*)+1 from z
加了union select 3 from dual 之后,執(zhí)行計(jì)劃走M(jìn)ERGE JOIN,這一點(diǎn)還沒(méi)想明白,歡迎指教。
(五)提前剔除奇數(shù)
WITH t0 AS (
SELECT 2*ROWNUM+1 rn FROM DUAL CONNECT BY ROWNUM <= (10000)/2-1
),
t 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)
SELECT COUNT(*) + 1 + 7 --2,3,5,7,11,13,17,19
FROM (SELECT rn
from t
MINUS
SELECT t1.rn * t2.rn
FROM t t1, t t2
WHERE t1.rn <= t2.rn
AND t1.rn BETWEEN 9 AND (SELECT SQRT(10000) FROM DUAL)
AND t1.rn * t2.rn < 10000)
其實(shí)后面的大部分寫(xiě)法都是采用提前篩選掉不合格的數(shù)字來(lái)減少源數(shù)據(jù)大小達(dá)到加快查詢(xún)速度。
全文完。
總結(jié)
以上是生活随笔為你收集整理的oracle质数怎么算,借花献佛之使用Oracle sql求质数(笔记)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: oracle 分列,SQL 问题 如何
- 下一篇: c语言用正数的形式求最大值最小值,C语言