I’m trying to generate a big table of consecutive numbers in MySQL.
I just want 2 columns; a primary key and a numbers column with a range of 0-X, where X is very large. Approx. 64,000 rows should do it. I’ve tried this code with no success:
CREATE TABLE numbers ( number INT NOT NULL CONSTRAINT XPKnumbers PRIMARY KEY CLUSTERED (number) ) INSERT INTO numbers (number) VALUES (0) DECLARE @i INT SET @i = 20 WHILE 0 < @i BEGIN INSERT INTO numbers (number) SELECT number + (SELECT 1 + Max(number) FROM numbers) FROM numbers SET @i = @i - 1 END SELECT * FROM numbers
and I get this error:
#1064 – You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘CONSTRAINT XPKnumbers PRIMARY KEY CLUSTERED (number) ) INSERT INTO n’ at line 3
Anybody have any suggestions to make this work?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You are missing semicolons, commas, and even after correcting syntax it is still not a good idea to select max from the table every time just to insert one more row in a loop.
Drop that and use generators from http://use-the-index-luke.com/blog/2011-07-30/mysql-row-generator :
CREATE OR REPLACE VIEW generator_16 AS SELECT 0 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 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15; CREATE OR REPLACE VIEW generator_256 AS SELECT ( ( hi.n << 4 ) | lo.n ) AS n FROM generator_16 lo, generator_16 hi; CREATE OR REPLACE VIEW generator_4k AS SELECT ( ( hi.n << 8 ) | lo.n ) AS n FROM generator_256 lo, generator_16 hi; CREATE OR REPLACE VIEW generator_64k AS SELECT ( ( hi.n << 8 ) | lo.n ) AS n FROM generator_256 lo, generator_256 hi; CREATE OR REPLACE VIEW generator_1m AS SELECT ( ( hi.n << 16 ) | lo.n ) AS n FROM generator_64k lo, generator_16 hi;
And if for whatever reason you really need a table of numbers just do:
INSERT INTO numbers(number) SELECT n FROM generator_64k WHERE n < 64000
Method 2
Here’s a quick and simple way to generate a list of numbers. Running this query using MySQL produced a list of 64,000 numbers in sequence in 0.561 seconds.
set @i = 0; SELECT * FROM ( SELECT @i:<a href="https://getridbug.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2a176a43">[email protected]</a>+1 AS IndexNo FROM my_table -- any real table can be used here HAVING @i < 64000 )x
Method 3
You’re missing a comma between the column and constraint declaration:
CREATE TABLE numbers ( number INT NOT NULL, CONSTRAINT XPKnumbers PRIMARY KEY CLUSTERED (number) )
Method 4
From MySQL 8.0 you could use RECURSIVE CTE to generate tally table:
SET @@cte_max_recursion_depth = 5000; WITH RECURSIVE cte AS ( SELECT 1 AS i UNION ALL SELECT i+1 FROM cte WHERE i < 3000 ) SELECT * FROM cte;
Method 5
I needed to create a numbers table in MySQL today but didn’t have permissions to create a view object so decided to modify the earlier answer by @piotrm.
So instead of a persisted object, a CTE with a bit of “fun”, binary-style math” can do the job:
WITH n (number) AS (
SELECT 0
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
)
SELECT (d.number * Pow(8, 3))
+ (c.number * Pow(8, 2))
+ (b.number * Pow(8, 1))
+ (a.number * Pow(8, 0)) AS number
FROM n AS a
CROSS
JOIN n AS b
CROSS
JOIN n AS c
CROSS
JOIN n AS d
;
This will generate you 4,096 numbers and the pattern can be easily extended to give you more as required.
P.S.: the bit-shift magic in @piotrm’s answer is cool, but I find it harder to follow… hence why I’ve swapped to some “simple” math.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0