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
To answer the question you asked:
Can you please let me know the issue in this code?
The problem with your code is that you never reset @i
back to 1 when you iterate to the next value of @j
.
...
END
SET @i = 1 --add this line to fix it
SET @j += 1
...
For fun (and I feel like I've likely answered someone's homework, but hey...), like a said, a Tally would be far faster:
WITH N AS (
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
FROM N N1, N N2, N N3), --1,000 Numbers
Remainders AS(
SELECT T1.I AS [Integer],
T2.I AS Divider,
T1.I % T2.I AS Remainder
FROM Tally T1
JOIN Tally T2 ON T1.I >= T2.I)
SELECT R.[Integer] AS PrimeNumber
FROM Remainders R
GROUP BY R.[Integer]
HAVING COUNT(CASE WHEN R.Remainder = 0 THEN 1 END) <= 2
ORDER BY R.[Integer];
This is pretty fast when you do it for 1,000 rows, but (unsurprisingly) execution time starts to exponentially increase as you increase the range.
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