SQL筛选actor_id为素数的演员的替代查询方案及1-3判定方法
素数actor_id筛选的优化方案与其他实现方式
首先明确前提:1不属于素数范畴,所以筛选逻辑默认直接排除1,同时保留2、3两个素数。
一、整合1/2/3校验的简化写法
你原有语句逻辑正确,但可以调整条件逻辑避免单独枚举2和3,把所有校验逻辑整合,优化后语句如下:
SELECT * FROM actor WHERE actor_id > 1 AND (MOD(actor_id, 2) != 0 OR actor_id = 2) AND (MOD(actor_id, 3) != 0 OR actor_id = 3) ORDER BY actor_id;
这个写法和你原有逻辑完全等价,不用单独写OR匹配2和3,可读性也更高。如果需要覆盖更大范围的素数判断,还可以用子查询做统一校验:
SELECT * FROM actor WHERE actor_id > 1 AND NOT EXISTS ( SELECT 1 FROM (SELECT 2 AS num UNION SELECT 3 UNION SELECT 5 UNION SELECT 7) t WHERE t.num <= FLOOR(SQRT(actor_id)) AND MOD(actor_id, t.num) = 0 ) ORDER BY actor_id;
二、其他实现方式
- 预生成素数表关联查询
如果actor_id的上限是固定的(比如演员表ID最大不超过2000),可以提前创建一张素数参考表,查询性能最高,后续复用也方便:
-- 素数表只需要生成维护一次 CREATE TABLE prime_numbers (prime INT PRIMARY KEY); -- 插入对应范围内所有素数后,查询语句非常简洁 SELECT a.* FROM actor a JOIN prime_numbers p ON a.actor_id = p.prime ORDER BY a.actor_id;
- 递归CTE通用素数校验
如果需要适配任意范围的actor_id,不想提前维护素数表,可以用递归CTE实现通用的素数判断:
WITH RECURSIVE divisors(n) AS ( SELECT 2 UNION ALL SELECT n+1 FROM divisors WHERE n <= (SELECT MAX(actor_id) FROM actor) ) SELECT * FROM actor a WHERE a.actor_id > 1 AND NOT EXISTS ( SELECT 1 FROM divisors d WHERE d.n <= FLOOR(SQRT(a.actor_id)) AND MOD(a.actor_id, d.n) = 0 ) ORDER BY a.actor_id;
小提示
你原来的写法要注意逻辑运算符优先级问题,AND优先级高于OR,如果后续新增筛选条件容易出现逻辑偏差,建议即使保留原有写法,也给条件加上括号明确逻辑边界:
SELECT * FROM actor WHERE ( actor_id > 1 AND mod(actor_id, 2) != 0 AND mod(actor_id, 3) != 0 ) OR actor_id IN (2,3) ORDER BY actor_id;
内容的提问来源于stack exchange,提问作者indigo
相关产品推荐
相关产品推荐

