一道MySQL笔试题: 输出 100 以内质数
在 MySQL 中输出 100 以内的质数,可以通过几种方法实现。以下是两种主要方法:使用存储过程和使用纯 SQL 查询。
方法一:使用存储过程
这种方法使用 MySQL 存储过程来生成质数,代码清晰易懂。
DELIMITER $$CREATE PROCEDURE GeneratePrimes(IN max_num INT)
BEGINDECLARE i INT DEFAULT 2;DECLARE j INT DEFAULT 2;DECLARE is_prime BOOLEAN;DECLARE result TEXT DEFAULT '';-- 循环检查每个数字是否为质数WHILE i <= max_num DOSET is_prime = TRUE;SET j = 2;-- 检查当前数字是否为质数WHILE j * j <= i DOIF i % j = 0 THENSET is_prime = FALSE;LEAVE inner_loop;END IF;SET j = j + 1;END WHILE;-- 如果是质数,添加到结果中IF is_prime THENIF result = '' THENSET result = CONCAT(result, i);ELSESET result = CONCAT(result, '&', i);END IF;END IF;SET i = i + 1;END WHILE;-- 输出结果SELECT result AS prime_numbers;
END$$DELIMITER ;-- 调用存储过程生成100以内的质数
CALL GeneratePrimes(100);
方法二:使用纯 SQL 查询
这种方法使用递归 CTE 和复杂的查询逻辑来生成质数。
WITH RECURSIVE numbers(n) AS (-- 生成2到100的数字序列SELECT 2UNION ALLSELECT n + 1 FROM numbers WHERE n < 100
),
primes AS (-- 筛选出质数SELECT n1.nFROM numbers n1WHERE NOT EXISTS (SELECT 1FROM numbers n2WHERE n2.n > 1 AND n2.n < n1.n AND n1.n % n2.n = 0)
)
-- 将结果连接成一个字符串,用&分隔
SELECT GROUP_CONCAT(n ORDER BY n SEPARATOR '&') AS prime_numbers
FROM primes;
方法三:使用数字表和复杂查询
如果你有一个包含连续数字的表(或者创建一个临时表),可以使用以下方法:
-- 创建临时数字表(如果不存在)
CREATE TEMPORARY TABLE IF NOT EXISTS numbers (n INT);-- 清空并插入2到100的数字
TRUNCATE TABLE numbers;
INSERT INTO numbers
WITH RECURSIVE seq (n) AS (SELECT 2UNION ALLSELECT n + 1 FROM seq WHERE n < 100
)
SELECT * FROM seq;-- 查询质数
SELECT GROUP_CONCAT(n ORDER BY n SEPARATOR '&') AS prime_numbers
FROM numbers n1
WHERE NOT EXISTS (SELECT 1FROM numbers n2WHERE n2.n > 1 AND n2.n <= SQRT(n1.n) AND n1.n % n2.n = 0
);
方法四:优化版本(使用平方根优化)
这个版本通过只检查到平方根来优化性能:
WITH RECURSIVE numbers(n) AS (SELECT 2UNION ALLSELECT n + 1 FROM numbers WHERE n < 100
)
SELECT GROUP_CONCAT(n ORDER BY n SEPARATOR '&') AS prime_numbers
FROM numbers n1
WHERE NOT EXISTS (SELECT 1FROM numbers n2WHERE n2.n BETWEEN 2 AND SQRT(n1.n) AND n1.n % n2.n = 0
);
结果
无论使用哪种方法,最终结果都应该是:
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
性能比较
- 存储过程:最灵活,代码最清晰,但需要创建存储过程
- 纯SQL查询:不需要创建额外对象,但查询可能较复杂
- 数字表方法:如果有现成的数字表,性能可能更好
- 优化版本:通过只检查到平方根,性能最佳
注意事项
- 如果使用存储过程,需要有创建存储过程的权限
- 递归CTE在MySQL 8.0及以上版本支持
- 对于更大的数字范围,可能需要优化算法或增加执行时间
选择哪种方法取决于你的具体需求和MySQL版本。对于100以内的质数,所有方法都应该能快速完成。