WITH RECURSIVE Numbers AS (
SELECT
2 AS num
UNION
SELECT
num+1
FROM Numbers
WHERE num <= 1000
)
SELECT
GROUP_CONCAT(num SEPARATOR '&') AS prime_numbers
FROM
Numbers AS n
WHERE NOT EXISTS (
SELECT
1
FROM
Numbers AS n2
WHERE
n2.num > 1
AND n2.num < n.num
AND n.num % N2.num = 0
)
AND num <= 1000
;
delimiter $$
create procedure getPrime(IN n int, OUT result varchar(2000))
Begin
declare j, i, flag int; -- Declare variables
set j:=2;
set result:=' ';
while(j<n) do -- Loop from 2 to n
set i:=2;
set flag:=0;
while(i<=j) do -- Loop from 2 to j
if(j%i=0)then
set flag:=flag+1;
end if;
set i:=i+1; -- Increment i
end while;
if (flag=1) then
set result:=concat(result, j, '&'); -- Concat the prime number with '&'
end if ;
set j:=j+1; -- * Increment j
end while;
End
$$
call getPrime(1000, @result);
select substr(@result, 1, length(@result)-1); -- To remove last character
;
DELIMITER ^^
CREATE PROCEDURE prime_numbers()
BEGIN
DECLARE n INT DEFAULT 3;
DECLARE res VARCHAR(2000) DEFAULT "2";
loop1: WHILE n <= 1000 DO
SET @i = 2;
SET @isPrime = 1;
loop2: WHILE @i <= CEIL(n/2) DO
IF n % @i = 0 THEN
SET @isPrime = 0;
LEAVE loop2;
END IF;
SET @i = @i+1;
END WHILE loop2;
IF @isPrime = 1 THEN
SET res = CONCAT(res,"&",n);
END IF;
SET n = n+1;
END WHILE loop1;
SELECT res;
END ^^
DELIMITER ;
CALL prime_numbers();
-- Stored Procedure 만들기
DELIMITER $$
CREATE PROCEDURE getPrime(
IN n INT
, OUT result VARCHAR(16383)
)
BEGIN
DECLARE j, i, flag INT;
SET j:=2;
SET result:=' ';
WHILE (j<n) DO
SET i:=2;
SET flag:=0;
WHILE (i<j) DO
IF (j%i=0) THEN
SET flag:=flag+1;
END IF;
SET i:=i+1;
END WHILE;
IF (flag=1) THEN
SET result:=CONCAT(result, j, '&');
END IF;
SET j:=j+1;
END WHILE;
END $$
-- 만든 Stored Procedure 호출(call)하기
CALL getPrime(1000, @result);
SELECT SUBSTR(@result, 1, LENGTH(@result)-1);
https://poqw.tistory.com/24
https://blog.duveen.me/19
https://www.geeksforgeeks.org/stored-procedure-for-prime-numbers-in-mysql/
https://three-pleasure.tistory.com/256
https://passwd.tistory.com/entry/MySQL-%EC%82%AC%EC%9A%A9%EC%9E%90-%EC%A0%95%EC%9D%98-%EB%B3%80%EC%88%98
SELECT GROUP_CONCAT(NUMB SEPARATOR '&')
FROM (
SELECT @num:=@num+1 as NUMB FROM
information_schema.tables t1,
information_schema.tables t2,
(SELECT @num:=1) tmp
) tempNum
WHERE NUMB<=1000 AND NOT EXISTS(
SELECT * FROM (
SELECT @nu:=@nu+1 as NUMA FROM
information_schema.tables t1,
information_schema.tables t2,
(SELECT @nu:=1) tmp1
LIMIT 1000
) tatata
WHERE FLOOR(NUMB/NUMA)=(NUMB/NUMA) AND NUMA<NUMB AND NUMA>1
)
WITH RECURSIVE t AS (
SELECT 2 AS nums
UNION
SELECT nums + 1
FROM t
WHERE nums < 1000
)
SELECT GROUP_CONCAT(nums SEPARATOR '&')
FROM t
WHERE nums NOT IN (
SELECT DISTINCT a.nums
FROM t a
JOIN t b
ON b.nums <= FLOOR(SQRT(a.nums))
AND a.nums % b.nums = 0
)
"This is so much more elegant than the loop-based way, although maybe not as practical for extremely large input ranges."
: Self-Directed Learning
※ 참고한 블로그
→ 다른 내용도 설명이 잘 되어 있으니 정독 추천
WHILE expression DO
statements
END WHILE
DELIMITER $$
DROP PROCEDURE IF EXISTS test_mysql_while_loop$$
CREATE PROCEDURE test_mysql_while_loop()
BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
SET x = 1;
SET str = '';
WHILE x <= 5 DO
SET str = CONCAT(str,x,',');
SET x = x + 1;
END WHILE;
SELECT str;
END$$
DELIMITER ;
CALL test_mysql_while_loop();
만약 x 변수를 초기화하지 않는다면 x 변수의 기본값은 NULL이 된다는 것을 알고 있어야 한다. 그러므로 WHILE문의 조건은 항상 TRUE가 된다. 그리고 무한 반복에 빠지게 된다.