2008-10-09 72 views
39

如何从MySQL查询生成一系列连续的数字(每行一个),以便我可以将它们插入到表中?在MySQL中生成一系列数字

例如:

nr 
1 
2 
3 
4 
5 

我想只使用MySQL的这个(不是PHP或其他语言)。

+0

是否要将其添加到现有记录或全新表格? – Sklivvz 2008-10-09 11:07:59

+0

这将是新的记录。 – nicudotro 2008-10-09 11:10:40

+1

为什么你不能使用auto_increment列? – Rob 2008-10-09 14:10:26

回答

25

如果您需要表中的记录并且希望避免并发问题,请按照以下步骤操作。

首先您必须在其中存储您的记录

CREATE TABLE `incr` (
    `Id` int(11) NOT NULL auto_increment, 
    PRIMARY KEY (`Id`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8; 

表其次创建这样一个存储过程:

DELIMITER ;; 
CREATE PROCEDURE dowhile() 
BEGIN 
    DECLARE v1 INT DEFAULT 5; 
    WHILE v1 > 0 DO 
    INSERT incr VALUES (NULL); 
    SET v1 = v1 - 1; 
    END WHILE; 
END;; 
DELIMITER ; 

最后拨打SP:

CALL dowhile(); 
SELECT * FROM incr; 

结果

Id 
1 
2 
3 
4 
5 
5
DECLARE i INT DEFAULT 0; 

WHILE i < 6 DO 
    /* insert into table... */ 
    SET i = i + 1; 
END WHILE; 
54

这里有一种方法来做到基于set的没有循环。这也可以作为重复使用的视图。这个例子显示了从0到999的序列的生成,但是当然,它可以被修改以适合。

INSERT INTO 
    myTable 
    (
    nr 
    ) 
SELECT 
    SEQ.SeqValue 
FROM 
(
SELECT 
    (HUNDREDS.SeqValue + TENS.SeqValue + ONES.SeqValue) SeqValue 
FROM 
    (
    SELECT 0 SeqValue 
    UNION ALL 
    SELECT 1 SeqValue 
    UNION ALL 
    SELECT 2 SeqValue 
    UNION ALL 
    SELECT 3 SeqValue 
    UNION ALL 
    SELECT 4 SeqValue 
    UNION ALL 
    SELECT 5 SeqValue 
    UNION ALL 
    SELECT 6 SeqValue 
    UNION ALL 
    SELECT 7 SeqValue 
    UNION ALL 
    SELECT 8 SeqValue 
    UNION ALL 
    SELECT 9 SeqValue 
    ) ONES 
CROSS JOIN 
    (
    SELECT 0 SeqValue 
    UNION ALL 
    SELECT 10 SeqValue 
    UNION ALL 
    SELECT 20 SeqValue 
    UNION ALL 
    SELECT 30 SeqValue 
    UNION ALL 
    SELECT 40 SeqValue 
    UNION ALL 
    SELECT 50 SeqValue 
    UNION ALL 
    SELECT 60 SeqValue 
    UNION ALL 
    SELECT 70 SeqValue 
    UNION ALL 
    SELECT 80 SeqValue 
    UNION ALL 
    SELECT 90 SeqValue 
    ) TENS 
CROSS JOIN 
    (
    SELECT 0 SeqValue 
    UNION ALL 
    SELECT 100 SeqValue 
    UNION ALL 
    SELECT 200 SeqValue 
    UNION ALL 
    SELECT 300 SeqValue 
    UNION ALL 
    SELECT 400 SeqValue 
    UNION ALL 
    SELECT 500 SeqValue 
    UNION ALL 
    SELECT 600 SeqValue 
    UNION ALL 
    SELECT 700 SeqValue 
    UNION ALL 
    SELECT 800 SeqValue 
    UNION ALL 
    SELECT 900 SeqValue 
    ) HUNDREDS 
) SEQ 
+12

这就是创新 – 2009-08-02 12:13:47

42

这里有一个硬件工程师的版本的匹兹堡DBA的解决方案:

SELECT 
    (TWO_1.SeqValue + TWO_2.SeqValue + TWO_4.SeqValue + TWO_8.SeqValue + TWO_16.SeqValue) SeqValue 
FROM 
    (SELECT 0 SeqValue UNION ALL SELECT 1 SeqValue) TWO_1 
    CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 2 SeqValue) TWO_2 
    CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 4 SeqValue) TWO_4 
    CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 8 SeqValue) TWO_8 
    CROSS JOIN (SELECT 0 SeqValue UNION ALL SELECT 16 SeqValue) TWO_16; 
+3

很好,在那里。 – 2012-05-19 03:57:56

12

比方说,你想通过100插入数字1到表。只要你有至少具有许多行(不要紧表的内容),其他一些表,那么这是我的首选方法:

INSERT INTO pivot100 
SELECT @ROW := @ROW + 1 AS ROW 
FROM someOtherTable t 
join (SELECT @ROW := 0) t2 
LIMIT 100 
; 

要与比其他东西开始了一系列1?只需更改连接上设置的@ROW即可。

6

大家都明白了,这是相当哈克所以请小心

SELECT id % 12 + 1 as one_to_twelve FROM any_large_table group by one_to_twelve 
0

“最短”的方式,我知道(在MySQL)用于创建一个表,一个长序列是(交叉)加入一个现有的表格。由于任何(公共)MySQL服务器有information_schema.COLUMNS表我会用它:

DROP TABLE IF EXISTS seq; 
CREATE TABLE seq (i MEDIUMINT AUTO_INCREMENT PRIMARY KEY) 
    SELECT NULL AS i 
    FROM information_schema.COLUMNS t1 
    JOIN information_schema.COLUMNS t2 
    JOIN information_schema.COLUMNS t3 
    LIMIT 100000; -- <- set your limit here 

通常一个连接应该足以创造超过100万行 - 但是,一个更加入不会伤害:-) - 不过不要忘记设定一个限制。

如果要包含0,应该“删除”AUTO_INCEMENT属性。

ALTER TABLE seq ALTER i DROP DEFAULT; 
ALTER TABLE seq MODIFY i MEDIUMINT; 

现在你可以插入0

INSERT INTO seq (i) VALUES (0); 

数和负数以及

INSERT INTO seq (i) SELECT -i FROM seq WHERE i <> 0; 

您可以

SELECT MIN(i), MAX(i), COUNT(*) FROM seq; 
0

我想分享的想法验证号码并不是一个确切的答案回答这个问题,但可以对某些人有用,所以我想分享一下。

如果您经常只需要有限的一组数字,那么创建一个包含您可能需要的数字的表格并且每次只使用该表格可能会有所帮助。例如:

CREATE TABLE _numbers (num int); 
INSERT _numbers VALUES (0), (1), (2), (3), ...; 

只有当你需要的数字低于某一合理的限度,所以不要用它来生成序列1 ... 1万,但是可用于数字1这可应用于...例如10K。

如果你在_numbers表号的这个名单,那么你可以这样写查询,获得一个字符串的单个字符:

SELECT number, substr(name, num, 1) 
    FROM users 
    JOIN _numbers ON num < length(name) 
    WHERE user_id = 1234 
    ORDER BY num; 

如果你需要比10K更大的数字,那么你可以加入表格本身:

SELECT n1.num * 10000 + n2.num 
    FROM _numbers n1 
    JOIN _numbers n2 
    WHERE n1 < 100 
    ORDER BY n1.num * 10000 + n2.num; -- or just ORDER BY 1 meaning the first column