问题
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