在SQL中插入多个记录,其中值是单个查询中定义范围的所有组合

时间:2013-12-30 13:59:15

标签: mysql sql insert where-in

如何编写sql查询

我需要像

这样的东西
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) 

现在的数据库结构

用户ID,credID,时间 10,34,2013-12-12 10,54,2013-12-12

所以我必须得到

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
....

逻辑算法必须像

对于范围内的每个userID(10,11,12,13,14,15,16,17,18,19,20) 插入带有credID值(1,2,3,4,5)的新字段

对于单个userID,我可以使用查询创建单个credID insert into database.table (userID,credID,time) values (10,1,2013-12-12) 但我需要为多个userID插入多个credID

2 个答案:

答案 0 :(得分:2)

尝试这种方式:

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

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


EDIT点。

如果这两个数字列表密集,那么还有一个数字表的技巧:

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
;

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


EDIT点。

数字表还有另一种技巧 如果要将这两个列表作为逗号分隔的字符串传递,请尝试以下查询:

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
;

演示 - &gt; http://www.sqlfiddle.com/#!9/83c86/1

答案 1 :(得分:0)

这在SQL 一般中是不可能的,除非这些值范围是某些其他表的一部分。在这种情况下,您可以通过加入范围而无需任何连接键来实现 - 这将产生所需的笛卡尔积:

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))

但正如我上面所说 - 在此代码中,我们假设database.table包含所有列出的用户ID和所有credIDs 1..5。但这并不一定是阻碍 - 相反,在大多数实际情况下你需要确保存在这些值 - 不一定在你插入的表中,但通常在数据库的另一个表中(然后你必须相应地修改子查询。)

但是,如果例如,如你所说的那样,credID是 new 并且还没有包含在任何表格中,你必须使用@kordiko的方法(对他有信用)并将其合并到上面的查询中:

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