如何在MySQL中用递归CTE插入不重复随机数且不使用存储过程
错误原因
你遇到的报错是SQL对递归CTE的强制语法限制导致的:递归CTE的递归成员不允许对递归表本身进行子查询、聚合类引用,因此你原本写在递归条件里的实时去重逻辑无法实现。
可行实现方案
方案1:超量生成后去重取数(执行速度快,兼容性高)
思路是先生成超出目标数量2-3倍的随机数,再通过DISTINCT去重后取需要的条数。8位随机数总共有1亿种可能,生成20-30万条随机数去重后拿10万条的成功率接近100%,性能损耗极低。
INSERT into `table` (row1,row2) WITH RECURSIVE cte AS ( SELECT 0 num, LPAD(FLOOR(RAND() * 99999999),8,0) random_num UNION ALL SELECT num+1, LPAD(FLOOR(RAND() * 99999999),8,0) random_num FROM cte WHERE num < 300000-1 -- 生成3倍目标量,确保去重后条数足够 ) SELECT DISTINCT random_num, null FROM cte -- 若目标表已有数据,需新增下面一行排除已存在的数值 -- WHERE random_num NOT IN (SELECT row1 FROM `table`) LIMIT 100000;
方案2:连续序列随机抽取(100%无重复,无碰撞风险)
如果需要绝对保证生成的随机数不重复,可以先生成全量8位连续数字序列,再随机排序取指定条数,天然无重复。
INSERT into `table` (row1,row2) WITH RECURSIVE cte AS ( SELECT 0 num UNION ALL SELECT num+1 FROM cte WHERE num < 99999999 -- 生成所有0-99999999的连续整数 ) SELECT LPAD(num,8,0), null FROM cte -- 若目标表已有数据,需新增下面一行排除已存在的数值 -- WHERE num NOT IN (SELECT row1 FROM `table`) ORDER BY RAND() -- 对所有序列随机排序 LIMIT 100000;
小提示:如果你的目标表
row1字段已经设置了唯一约束,可以在INSERT语句中加入IGNORE关键字,插入时重复的随机数会被自动忽略,只要生成的随机数总条数足够,就能最终插入符合要求的不重复数据。
内容的提问来源于stack exchange,提问作者FdS
相关产品推荐
相关产品推荐

