First 1000 Prime Numbers with SQL Server

前端 未结 3 1594
刺人心
刺人心 2021-01-23 18:04

I got program for Prime which gives only 2 as output. It should give me all based on java program I wrote.

Here is SQL I have created for Prime numbers. It is in SQL Ser

3条回答
  •  栀梦
    栀梦 (楼主)
    2021-01-23 18:47

    I had a similar solution to Larnu's, but went into a meeting and didn't want it to go to waste. It produces 1229 prime numbers (all the prime numbers lower than 10,000), in 7 seconds.

    WITH 
    E(n) AS(
        SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0))E(n)
    ),
    E2(n) AS(
        SELECT a.n FROM E a, E b
    ),
    E4(n) AS(
        SELECT a.n FROM E2 a, E2 b
    ),
    cteTally(n) AS(
        SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) n
        FROM E4
    )
    SELECT n
    FROM cteTally t
    WHERE (SELECT COUNT(*)
                    FROM cteTally i
                    WHERE t.n % i.n = 0
                    AND i.n < t.n) = 1;
    

    It can run a lot faster if we're allowed to use some hard-coded values.

    WITH 
    E(n) AS(
        SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0))E(n)
    ),
    E2(n) AS(
        SELECT a.n FROM E a, E b
    ),
    E4(n) AS(
        SELECT a.n FROM E2 a, E2 b
    ),
    cteTally(n) AS(
        SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) n
        FROM E4
    )
    SELECT *
    FROM (VALUES(2),(3),(5),(7))x(n)
    UNION ALL
    SELECT n
    FROM cteTally t
    WHERE t.n % 2 <> 0
    AND t.n % 3 <> 0 
    AND t.n % 5 <> 0 
    AND t.n % 7 <> 0 
    AND (SELECT COUNT(*)
                    FROM cteTally i
                    WHERE t.n % i.n = 0
                    AND i.n < t.n) = 1;
    

    EDIT: The last version takes 1 second to find all the prime numbers below 10K, but goes up to 2.5 minutes to get all the prime numbers below 100K (9592 prime numbers).

    EDIT 2: Here's an option that combines both versions to improve performance on large data sets. It won't need a large tally table either.

    DECLARE @j INT = 1;
    
    CREATE TABLE #Primes( N int);
    BEGIN TRY
        BEGIN TRANSACTION;
    
        WHILE @j <= 1000000
        BEGIN
            INSERT INTO #Primes
            SELECT @J
            FROM #Primes
            WHERE @j % n = 0
            HAVING COUNT(*) <= 1;
    
            SET @j += 1;
        END;
    
        COMMIT TRANSACTION;
    
        SELECT * 
        FROM #Primes
        WHERE N <> 1;
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION;
        THROW;
    END CATCH;
    
    DROP TABLE #Primes;
    GO 
    

提交回复
热议问题