oracle质数怎么算,借花献佛之使用Oracle sql求质数(笔记)
首先聲明一點,文章內容從itpub論壇上看到的,原文鏈接外鏈網址已屏蔽,本文主要是記錄下筆記,原文中有更詳細的分析。使用sql求質素沒什么實用價值,重要的是思路。
(一)最簡單的方法
思路:將2和所有大于等于3小于XX的奇數取出來,做一中間結果集t。然后逐一校驗t中的每個N是否是質數。如果發現一個數字N不能被其他所有數字整除——當然,這些數字要小于等于SQRT(N),那么N就是質數
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的數都列出來,作為一個全集,然后減去所有的合數,即可得到素數集合
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))
(三)改進的篩選法
思路:除了2之外的偶數,可以從全集和合數集中排除
WITH t AS (
--2-10000/2
SELECT ROWNUM+1 rn FROM DUAL CONNECT BY ROWNUM <= 10000/2-1
)
,t_odd AS (
--奇數
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)
另一種寫法:排除偶數
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執行計劃 走MERGE 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 之后,執行計劃走MERGE JOIN,這一點還沒想明白,歡迎指教。
(五)提前剔除奇數
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)
其實后面的大部分寫法都是采用提前篩選掉不合格的數字來減少源數據大小達到加快查詢速度。
全文完。
總結
以上是生活随笔為你收集整理的oracle质数怎么算,借花献佛之使用Oracle sql求质数(笔记)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: oracle 分列,SQL 问题 如何
- 下一篇: linux命令录制,怎样在Linux上录