Insert multiple records in SQL where values are all combinations of defined ranges in single query

断了今生、忘了曾经 提交于 2019-12-24 03:29:12

问题


How to write sql query

I need something like

Insert Into database.table (userID,credID,time) 
values 
userId = for all in (10,15,12,17,14,267,16,689,18,7659,20)
credID = for all in (1,2,3,4,5) 
time = constant (forall the same) 

now database structure

userID,credID,time 10,34,2013-12-12 10,54,2013-12-12

so i must get

userID,credID,time
10,34,2013-12-12
10,54,2013-12-12
10,1,2013-12-12
10,2,2013-12-12
10,3,2013-12-12
10,4,2013-12-12
10,5,2013-12-12
11,1,2013-12-12
11,2,2013-12-12
11,3,2013-12-12
11,4,2013-12-12
11,5,2013-12-12
....

for logical algoritm must be like

for each userID in range (10,11,12,13,14,15,16,17,18,19,20) insert new fields with credID values (1,2,3,4,5)

For single userID i can create single credID with query insert into database.table (userID,credID,time) values (10,1,2013-12-12) but i need to insert multiple credID for multiple userID


回答1:


Try this way:

INSERT INTO table1( userID,credID,time)
SELECT x,y,'2013-12-12' 
FROM (
  SELECT 1 As x union
  SELECT 2 union
  SELECT 3 union
  SELECT 4 union
  SELECT 5
) xx
CROSS JOIN (
  SELECT 10 As y union
  SELECT 11 union
  SELECT 12 union
  SELECT 13 union
  SELECT 15 union
  SELECT 16 union
  SELECT 17 union
  SELECT 18 union
  SELECT 19 union
  SELECT 20
) yy

Demo: http://www.sqlfiddle.com/#!2/8398d/1


EDIT.

If these two lists of numbers are dense, there is another trick with table of numbers:

CREATE TABLE numbers( x int primary key auto_increment );

INSERT INTO numbers
SELECT null FROM information_schema.columns
LIMIT 100;

CREATE TABLE   table2
  (userID int,credID int,time date);

INSERT INTO table2( userID,credID,time)
SELECT n1.x,n2.x,'2013-12-12' 
FROM numbers n1
CROSS JOIN numbers n2
WHERE n1.x BETWEEN 1 AND 5
  AND n2.x BETWEEN 10 AND 20
;

demo: http://www.sqlfiddle.com/#!9/e121d/1


EDIT.

There is an another trick with the table of numbers.
If you want to pass these two lists as comma separated strings, then try this query:

CREATE TABLE numbers( x int primary key auto_increment );

INSERT INTO numbers
SELECT null FROM information_schema.columns
LIMIT 100;

CREATE TABLE   table1
  (userID int,credID int,time date);

INSERT INTO table1( userID,credID,time)
SELECT xx,yy,'2013-12-12' 
FROM (
        SELECT reverse( if( locate(',',reverse(SUBSTRING_INDEX( y, ',', x ))) > 0,
                          substr( reverse(SUBSTRING_INDEX( y, ',', x )), 1, locate(',',reverse(SUBSTRING_INDEX( y, ',', x ))) -1 ),
                          reverse(SUBSTRING_INDEX( y, ',', x ))
                     )) AS xx
        FROM (  select '1,22,333,44,51,656'  y ) q
        JOIN numbers n
        ON n.x <= length( y ) - length( replace( y, ',','')) + 1
) q1
CROSS JOIN
(
        SELECT reverse( if( locate(',',reverse(SUBSTRING_INDEX( y, ',', x ))) > 0,
                          substr( reverse(SUBSTRING_INDEX( y, ',', x )), 1, locate(',',reverse(SUBSTRING_INDEX( y, ',', x ))) -1 ),
                          reverse(SUBSTRING_INDEX( y, ',', x ))
                     )) AS yy
        FROM (  select '111,222,3333,444,54,656'  y ) q
        JOIN numbers n
        ON n.x <= length( y ) - length( replace( y, ',','')) + 1
) q2
;

Demo --> http://www.sqlfiddle.com/#!9/83c86/1




回答2:


This is not possible in SQL in general, unless those value ranges are part of some other table. In that case, you can do it by joining the ranges without any joining key - that will produce the desired cartesian product:

insert into database.table (userID,credID,time)
select userID, credID, '2011-12-12'
from (select userID
      from database.table
      where userID in (10,15,12,17,14,267,16,689,18,7659,20))
  join (select credID 
        from database.table
        where credID in (54, 34, 1, 2, 3, 4, 5))

But as I said above - in this code we assume that the database.table contains all listed userIDs and all credIDs 1..5. But that's not necessarily a hinderance - on the contrary, in most practical situations you need to assure that those values exist - not necessarily in the table you insert into, but usually in another table in the database (then you have to modify the subqueries accordingly).

However if for example the credID are new as you said and not contained in any table yet, you have to use approach of @kordiko (credit to him) and combine it in the query above:

insert into database.table (userID,credID,time)
select userID, credID, '2011-12-12'
from (select userID
      from database.table
      where userID in (10,15,12,17,14,267,16,689,18,7659,20)) as t1
  join (select 34 as credID union 
        select 54 union
        select 1 union
        select 2 union
        select 3 union
        select 4 union
        select 5
        ) as t2


来源:https://stackoverflow.com/questions/20841036/insert-multiple-records-in-sql-where-values-are-all-combinations-of-defined-rang

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!