68 Stimmen

Generierung eines Zahlenbereichs in MySQL

Wie generiere ich einen Bereich von aufeinanderfolgenden Zahlen (eine pro Zeile) aus einer MySQL-Abfrage, so dass ich sie in eine Tabelle einfügen kann?

Zum Beispiel:

nr
1
2
3
4
5

Ich möchte dafür nur MySQL verwenden (nicht PHP oder andere Sprachen).

0 Stimmen

Möchten Sie dies zu bestehenden Datensätzen oder zu einer völlig neuen Tabelle hinzufügen?

1 Stimmen

Warum können Sie keine auto_increment-Spalte verwenden?

2voto

Paul Spiegel Punkte 29427

Der "kürzeste" Weg, den ich (in MySQL) kenne, um eine Tabelle mit einer langen Sequenz zu erstellen, ist die (Kreuz-)Verknüpfung einer bestehenden Tabelle mit sich selbst. Da jeder (gewöhnliche) MySQL-Server die information_schema.COLUMNS Tabelle würde ich sie verwenden:

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

Normalerweise sollte ein Join ausreichen, um über 1 Mio. Zeilen zu erzeugen - aber ein weiterer Join kann nicht schaden :-) - Vergessen Sie nur nicht, ein Limit zu setzen.

Wenn Sie Folgendes aufnehmen möchten 0 sollten Sie die Funktion "entfernen". AUTO_INCEMENT Eigentum.

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

Jetzt können Sie einfügen 0

INSERT INTO seq (i) VALUES (0);

und auch negative Zahlen

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

Sie können die Zahlen überprüfen mit

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

2voto

Csongor Halmai Punkte 2513

Die Idee, die ich mit Ihnen teilen möchte, ist keine präzise Antwort auf die Frage, kann aber für einige nützlich sein, so dass ich sie gerne mit Ihnen teilen möchte.

Wenn Sie häufig nur eine begrenzte Anzahl von Zahlen benötigen, kann es von Vorteil sein, eine Tabelle mit den Zahlen zu erstellen, die Sie benötigen, und nur diese Tabelle jedes Mal zu verwenden. Zum Beispiel:

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

Dies kann nur angewandt werden, wenn Sie Zahlen unterhalb einer bestimmten vernünftigen Grenze benötigen, also verwenden Sie es nicht für die Generierung der Sequenz 1...1 Million, sondern zum Beispiel für die Zahlen 1...10k.

Wenn Sie diese Liste von Nummern in der _numbers Tabelle können Sie dann Abfragen wie die folgende schreiben, um die einzelnen Zeichen einer Zeichenkette zu ermitteln:

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

Wenn Sie größere Zahlen als 10k benötigen, können Sie die Tabelle mit sich selbst verbinden:

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

2voto

Justin Levene Punkte 1505

Alle anderen Antworten sind gut, aber sie haben alle Geschwindigkeitsprobleme für größere Bereiche, weil sie MySQL zwingen, jede Zahl zu generieren und sie dann zu filtern.

Das Folgende lässt MySQL nur die Zahlen generieren, die benötigt werden, und ist daher schneller:

set @amount = 55; # How many numbers from zero you want to generate

select `t0`.`i`+`t1`.`i`+`t2`.`i`+`t3`.`i` as `offset`
from
(select 0 `i` 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) `t0`,
(select 0 `i` union select 10 union select 20 union select 30 union select 40 union select 50 union select 60 union select 70 union select 80 union select 90) `t1`,
(select 0 `i` union select 100 union select 200 union select 300 union select 400 union select 500 union select 600 union select 700 union select 800 union select 900) `t2`,
(select 0 `i` union select 1000 union select 2000 union select 3000 union select 4000 union select 5000 union select 6000 union select 7000 union select 8000 union select 9000) `t3`
where `t3`.`i`<@amount
and `t2`.`i`<@amount
and `t1`.`i`<@amount
and `t0`.`i`+`t1`.`i`+`t2`.`i`+`t3`.`i`<@amount;

Mit dem oben beschriebenen Verfahren können Sie bis zu 10.000 Zahlen (0 bis 9.999) generieren, ohne dass sich die Geschwindigkeit für niedrigere Zahlen verringert, egal wie niedrig sie sind.

1voto

dannymac Punkte 1471

Dies beruht auf einer früheren Antwort ( https://stackoverflow.com/a/53125278/2009581 ), ist aber mit MySQL 5.7 kompatibel. Es funktioniert für Replikate und Nur-Lese-Benutzer:

SELECT x1.N + x10.N*10 + x100.N*100 + x1000.N*1000
  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) x1,
       (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) x10,
       (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) x100,
       (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) x1000
 WHERE x1.N + x10.N*10 + x100.N*100 + x1000.N*1000 <= @max;

Es erzeugt ganze Zahlen im Bereich von [0, @max ].

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X