2008-10-09 10 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

Вот один из способов сделать это на основе набора без петель. Это также можно сделать в виде для повторного использования. В примере показано поколение последовательности от 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

Thats инновационный – 2009-08-02 12:13:47

42

Вот версия Аппаратный инженера решения Pittsburgh АБД:

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

Допустим, вы хотите, чтобы вставить цифры от 1 до 100 в таблицу. До тех пор, пока у вас есть какая-то другая таблица, которая имеет, по крайней мере, что многие строки (не имеет значения, содержания таблицы), то это мой предпочтительный метод:

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

Хочет диапазон, который начинается с чем-то другим, чем 1? Просто измените настройки @ROW на соединение.

6

Как вы понимаете, это довольно Hacky, так что используйте с осторожностью

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 

Обычно один присоединиться должен быть достаточно, чтобы создать более строки 1M - Но еще один присоединиться не повредит :-) - Только не забудьте установить предел.

Если вы хотите включить 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 
Смежные вопросы