Подтвердить что ты не робот

Создание диапазона чисел в MySQL

Как мне создать ряд последовательных чисел (по одной в строке) из запроса MySQL, чтобы я мог вставлять их в таблицу?

Например:

nr
1
2
3
4
5

Я хотел бы использовать для этого только MySQL (не PHP или другие языки).

4b9b3361

Ответ 1

Если вам нужны записи в таблице, и вы хотите избежать проблем с concurrency, вот как это сделать.

Сначала вы создаете таблицу для хранения ваших записей

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

Ответ 2

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

Ответ 3

Здесь версия инженерного инженера Pittsburgh 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;

Ответ 4

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

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

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

Ответ 5

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

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

Ответ 6

DECLARE i INT DEFAULT 0;

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

Ответ 7

"Самый короткий" способ, которым я знаю (в 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

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

Если вы хотите включить 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;

Ответ 8

Идея, которую я хочу рассказать, не является точным ответом на вопрос, но может быть полезна для некоторых, поэтому я хотел бы поделиться им.

Если вам часто нужен только ограниченный набор чисел, тогда полезно создать таблицу с числами, которые могут вам понадобиться, и просто использовать эту таблицу каждый раз. Например:

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