mysql生成1-N连续表

博客主要介绍了MySQL生成1-N连续表的两种方案。方案一为普通做法,效率不高;方案二以2的n次幂生成,效率较高,但生成特定数量记录需计算2^n的最小数。此外,还提及可利用数字辅助表生成连续时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

mysql生成1-N连续表

###准备

新建表nums

mysql> desc nums;
+-------+------------+------+-----+---------+-------+
| Field | Type       | Null | Key | Default | Extra |
+-------+------------+------+-----+---------+-------+
| id    | bigint(20) | NO   | PRI | NULL    |       |
+-------+------------+------+-----+---------+-------+
1 row in set (0.03 sec)

方案一

普通做法:

CREATE DEFINER=`root`@`localhost` PROCEDURE `generate_num`(IN `total` int)
BEGIN
	DECLARE s INT DEFAULT 1;
	WHILE s < total DO
		BEGIN
			INSERT INTO nums SELECT s;
			SET s=s+1;
		END;
	END WHILE;
END

调用存储过程:

call generate_num(1000)

Procedure executed successfully
时间: 185.239s

看起来效率并不高…

方案二

CREATE DEFINER=`root`@`localhost` PROCEDURE `generate_num_new`(IN `total` int)
BEGIN
	DECLARE s INT DEFAULT 1;
	INSERT INTO nums SELECT s;
	WHILE s*2 <= total DO
		BEGIN
			INSERT INTO nums SELECT id+s FROM nums;
			set s=s*2;
		END;
END WHILE;
END

分析一下,先插入{1},再插入{2},接着{3,4},接着{6,7,8,9}…,乍一看,似乎有规律:是以2的n次幂生成的

调用存储过程:

call generate_num_new(200000);

Procedure executed successfully
时间: 25.795s

效率杠杠的。。。,不过

mysql> select count(*) from nums;
+----------+
| count(*) |
+----------+
|   131072 |
+----------+
1 row in set (0.28 sec)

不过好像没有200000条,因为这是以2的n次幂生成的,如果真的要有200000条,就要求出2^n>200000的最小数

扩展

我们可以利用数字辅助表生成连续时间:

CREATE DEFINER=`root`@`localhost` PROCEDURE `createDateTimes`(IN `start` date,IN `end` date)
BEGIN
	#Routine body goes here...
	SELECT DATE_ADD(start,INTERVAL id-1 day) FROM nums WHERE id <=DATEDIFF(end,start)+1;
END

调用存储过程:

mysql> call createDateTimes('2019-03-12','2019-03-22');
+-----------------------------------+
| DATE_ADD(start,INTERVAL id-1 day) |
+-----------------------------------+
| 2019-03-12                        |
| 2019-03-13                        |
| 2019-03-14                        |
| 2019-03-15                        |
| 2019-03-16                        |
| 2019-03-17                        |
| 2019-03-18                        |
| 2019-03-19                        |
| 2019-03-20                        |
| 2019-03-21                        |
| 2019-03-22                        |
+-----------------------------------+
11 rows in set (0.04 sec)

Query OK, 0 rows affected (0.00 sec)
<think>我们被要求生成数字序列,在MySQL中没有直接的序列生成函数,但可以通过其他方法模拟。 常见方法包括: 1. 使用递归CTE(Common Table Expressions)生成连续数字(MySQL 8.0+) 2. 使用数字辅助(预先创建好的数字) 3. 使用内建的系统(如information_schema.columns)生成有限范围的数字 下面分别给出示例: ### 方法1:递归CTE(MySQL 8.0及以上) ```sql -- 生成0到9的数字 WITH RECURSIVE numbers AS ( SELECT 0 AS n UNION ALL SELECT n + 1 FROM numbers WHERE n < 9 ) SELECT * FROM numbers; ``` ### 方法2:创建数字辅助(适用于所有版本) ```sql -- 创建永久数字(例如0到9999) CREATE TABLE numbers ( n INT PRIMARY KEY ); -- 使用存储过程或批量插入初始化 -- 或者使用一次性的插入(例如插入0-99): INSERT INTO numbers (n) SELECT a.N + b.N * 10 AS n FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a, (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b; ``` ### 方法3:利用系统生成(适用于小范围) ```sql -- 利用information_schema.tables生成一定数量的数字(数量取决于中行数) SELECT @row := @row + 1 AS num FROM information_schema.tables, (SELECT @row := -1) r LIMIT 10; -- 生成0到9的数字 ``` ### 注意事项: 1. **递归CTE**:需要MySQL 8.0+,注意递归深度由`cte_max_recursion_depth`控制(默认1000) 2. **辅助**:适合频繁使用,但需预先创建 3. **系统**:生成数量受系统行数限制,可能不稳定 §§相关问题§§ 1. 如何在MySQL 5.7版本中生成连续数字序列? 2. 使用递归CTE生成数字序列时如何避免超出递归深度限制? 3. 除了information_schema.tables,还有哪些系统可用于生成数字? 4. 如何生成一个指定范围内的随机整数?</think>在 MySQL生成数字序列有多种方法,以下是三种常用技术: ### 方法一:递归 CTE(MySQL 8.0+) ```sql -- 生成 1-1000 的数字序列 WITH RECURSIVE numbers AS ( SELECT 1 AS n UNION ALL SELECT n + 1 FROM numbers WHERE n < 1000 ) SELECT * FROM numbers; ``` ### 方法二:使用系统(任何版本) ```sql -- 生成 1-100 的数字序列 SELECT (t1.n * 10 + t2.n) + 1 AS num FROM (SELECT 0 n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1, (SELECT 0 n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2 ORDER BY num LIMIT 100; ``` ### 方法三:JSON 函数(MySQL 8.0+) ```sql -- 生成 1-50 的数字序列 SELECT JSON_EXTRACT(CONCAT('[', REPEAT('0,', 49), '0]'), CONCAT('$[', n, ']')) + 1 AS num FROM ( SELECT 0 n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 ) digits LIMIT 50; ``` ### 使用场景建议: 1. **小范围序列**(<1000):系统方法(兼容性好) 2. **大范围序列**:递归 CTE(效率高) 3. **动态生成**:JSON 方法(灵活但稍慢) 4. **永久序列**:创建数字 `CREATE TABLE numbers (n INT PRIMARY KEY);` ### 性能注意: 1. 递归 CTE 默认最大深度 1000,可通过 `SET cte_max_recursion_depth = 1000000;` 调整 2. 系统方法在超过 10,000 行时效率下降 3. 频繁使用建议创建物理数字
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值