bashoogzaad
bashoogzaad

Reputation: 4781

INSERT rows multiple times based on a column value from another table

Mainly, I would like to insert a row in table 1 multiple times, based on an integer value in a column of table 2.

My situation

Table 2 contains a column 'SKU' and 'stock', and I would like to insert the 'SKU' and a timestamp into table 1. I want this row duplicated for 'stock'-value times in table 1.

I currently have the following query:

DECLARE @Count int = 1
WHILE @Count <= ....
BEGIN
    INSERT INTO table1 (table1.SKU, table1.timestamp_in) 
    SELECT table2.SKU, "some timestamp" FROM table2
    SET ...
END

I am not sure if this is the correct approach. I would like to run this loop for 'table2.stock' times.

My question is: Is this possible with just a SQL query, or should it be a better practice to build some (in my case) java code for this?

Upvotes: 1

Views: 2470

Answers (1)

fancyPants
fancyPants

Reputation: 51868

You don't need a procedure or anything like that. All you need is a table containing just numbers. I'm creating this table on the fly with this in this example:

SELECT aa.a + 10*bb.b + 100*cc.c AS numbers FROM (
SELECT 0 a 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) aa 
, (SELECT 0 b 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) bb 
, (SELECT 0 c 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) cc;

This creates the numbers 0 till 999.

Now you join your table2 with this numbers table in the range of stock. Your final query looks like this:

INSERT INTO table1 (table1.SKU, table1.timestamp_in) 
SELECT table2.SKU, "some timestamp" FROM table2
INNER JOIN (
    SELECT aa.a + 10*bb.b + 100*cc.c AS n FROM (
    SELECT 0 a 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) aa 
    , (SELECT 0 b 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) bb 
    , (SELECT 0 c 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) cc
) numbers ON numbers.n BETWEEN 0 AND table2.stock /*assuming you have no negative stock*/

Just make sure, that the numbers table contains more numbers than the highest value in the stock column.

Upvotes: 3

Related Questions