简体   繁体   中英

Get Prime Number records in Oracle using ROWNUM

I am trying to get all the prime(row) numbered records from my table.Can someone please shed some light on how to solve this problem?

Here is my sample data as below.

EMPID EMPNAME
1 A
2 B
3 C
4 D
5 E
6 F
7 G
8 H
9 I
10 J

Required output:

EMPID EMPNAME
2 B 
3 C
5 E
7 G

If I have huge data how do I get the output like this instead of using IN operator?

Sieve of Eratosthenes

CREATE TABLE primes (
    num number PRIMARY KEY
);

INSERT INTO primes (num)
SELECT LEVEL + 1
FROM dual
CONNECT BY LEVEL < 1000;

DELETE FROM primes p1
WHERE EXISTS (
    SELECT NULL
    FROM primes p2
    WHERE p2.num < p1.num
    AND MOD(p1.num, p2.num) = 0
);

And then

SELECT emps.*
FROM emps
INNER JOIN primes ON primes.num = emps.EMPID;

Or

SELECT EMPID, EMPNAME
FROM (
    SELECT ROWNUM AS rn, emps.EMPID, emps.EMPNAME
    FROM emps
)
INNER JOIN primes ON primes.num = rn;

If you don't want to calculate the primes, you could add them from existing data: List of small primes

select l prime_number
      from (select level l from dual connect by level <= 100)
         , (select level m from dual connect by level <= 100)
    -- where m<=l  --this doesnt matter but including it will perform better
     group by l
   having count(case l/m when trunc(l/m) then 1 end) in (1,2)
     order by l;

PRIME_NUMBER 1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

The following can be used:

with lvl as
(
  select level l from dual connect by level<=100
), unprime as(select l2.* from lvl l1,lvl l2 where l1.l<l2.l and mod(l2.l,l1.l)=0 and l1.l>1)
select lvl.l from lvl where l>1
minus select l from unprime;

Prime numbers up to 10 can be listed belows. Then join with your data on EMPID.

(SELECT LEVEL P FROM DUAL CONNECT BY ROWNUM<=10)
MINUS
(SELECT T1.P FROM
  (SELECT LEVEL P FROM DUAL CONNECT BY ROWNUM<=10) T1 JOIN
  (SELECT LEVEL D FROM DUAL CONNECT BY ROWNUM<=10) T2 ON mod(T1.P,T2.D)=0 AND T1.P>T2.D 
AND T2.D>1
)
MINUS (SELECT 1 FROM DUAL);

Assuming your table name is EMP:

WITH EMP AS
(
    SELECT 1 EMPID, 'A' EMPNAME FROM DUAL
    UNION ALL
    SELECT 2 EMPID, 'B' EMPNAME FROM DUAL
    --etc.
)
SELECT EMP.* FROM 
(
    (SELECT LEVEL P FROM DUAL CONNECT BY ROWNUM<=10)
    MINUS
    (SELECT T1.P FROM
      (SELECT LEVEL P FROM DUAL CONNECT BY ROWNUM<=10) T1 JOIN
      (SELECT LEVEL D FROM DUAL CONNECT BY ROWNUM<=10) T2 ON mod(T1.P,T2.D)=0 AND T1.P>T2.D 
    AND T2.D>1
    )
    MINUS (SELECT 1 FROM DUAL)
) T1,EMP WHERE T1.P=EMP.EMPID;

You can use the following query to Select all prime numbers

SQL> select l prime_number
  2    from (select level l from dual connect by level <= 100)
  3       , (select level m from dual connect by level <= 100)
  4   where m<=l
  5   group by l
  6  having count(case l/m when trunc(l/m) then 'Y' end) = 2
  7   order by l
  8  /

                          PRIME_NUMBER

                                     2
                                     3
                                     5
                                     7
                                    11
                                    13
                                    17
                                    19
                                    23
                                    29
                                    31
                                    37
                                    41
                                    43
                                    47
                                    53
                                    59
                                    61
                                    67
                                    71
                                    73
                                    79
                                    83
                                    89
                                    97

or this one:

SQL> with t as (select level l from dual connect by level <= 100)
  2  --
  3  SELECT l prim_num FROM
  4     (select * from t
  5       model
  6        dimension by (l dim)
  7        measures (l,2 temp)
  8         rules iterate (1000000) until (power(temp[1],2)>100)
  9           (l[DIM>TEMP[1]]=decode(mod(l[CV()],temp[1]),0,null,l[CV()]),
 10            temp[1]=min(l)[dim>temp[1]])
 11     )
 12  WHERE l IS NOT NULL
 13  /

and then just do this:

Select * 
from myTable 
where ROWNUM in (query)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM