2016-06-21 105 views
0

我有3个表格,一个是股票ID,一个是用户ID,第三个是股票ID,用户ID和用户是股票ID。插入到第三个表中有多对多关系

表1:

| stockID 
| 10001 
| 10002 
| 10003 
| 10004 

表2:

|userID 
| 11000 
| 11001 
| 11002 

表3:

|stockID |userID |userByStock 
| 10001 | 11000 0001 
| 10002 | 11000 0002 
| 10003 | 11000 0003 
| 10004 | 11000 0004 
| 10001 | 11001 0005 

在表3中,我想插入,并且具有所有用户都具有所有股票ID,并且userByStock总是递增1。

所以基本上,我需要抓住那些尚未在表3中存在的所有股票编号,并将它们添加到每个用户和1

我已经试过类似递增userByStock柱:

INSERT INTO table3 select table1.stockID FROM table1 WHERE table1.stockID NOT IN (SELECT stockID FROM table 3); 

但我被困

编辑:我还需要抓住从表2中已未在表3所有的用户ID,并把它们插入到表3

+2

在2个表上使用交叉连接以获取所有可能的组合,然后使用外部连接来确定需要插入哪些记录。 – Matt

+0

你是说你想在前面两个表中填充笛卡尔积,并在附加列中使用连续的唯一数字吗? –

+0

@ PM77-1我认为是的,是的。和马特,我大概可以找出交叉连接,但是我不知道如何让外部连接工作 – MJ95

回答

1
WITH cteAllPossibleCombinations AS (

    SELECT 
     StockId 
     ,UserId 
    FROM 
     Table1 
     CROSS JOIN Table2 
) 

, cteMaxUserByStock AS (
    SELECT MAX(CAST(userByStock AS INT)) AS MaxUserByStock 
    FROM 
     Table3 
) 

INSERT INTO Table3 (StockId, UserId) 
SELECT StockId, UserId, userByStock = m.MaxUserByStock + ROW_NUMBER() OVER (PARTITION BY 1) 
FROM 
    Table3 t 
    LEFT JOIN cteAllPossibleCombinations x 
    ON t.StockId = x.StockId 
    AND t.UserId = x.UserId 
    CROSS JOIN cteMaxUserByStock m 
WHERE 
    x.StockId IS NULL; 

我想如果你可以修改表3并使其成为真正的身份/自动增量列,但如果不仅仅是将最大值与row_number结合起来,你应该很好。你也可以在WHERE()IN SELECT答案中使用相同的技巧。

+0

谢谢我忘了补充说,当我看到Postgres我现在添加它。 – Matt

0

你可以在不

INSERT INTO table3 select table1.stockID, table2.userID 
    FROM table1, table2 
    WHERE (table1.stockID, table2.userID) NOT IN (SELECT stockID, userID FROM table 3); 
0
create table table3 (stockId smallint unsigned not null, userId smallint unsigned not null, userByStock smallint zerofill unsigned auto_increment primary key); 

    insert into table3 (stockId, userId) select table1.stockId, table2.userId from table1 cross join table2; 


    stockId | userId | userByStock | 
    +---------+--------+-------------+ 
    |  1 |  1 |  00001 | 
    |  2 |  1 |  00002 | 
    |  1 |  2 |  00003 | 
    |  2 |  2 |  00004 | 
    |  1 |  3 |  00005 | 
    |  2 |  3 |  00006 | 
    +---------+--------+-------------+ 

使用选择两个表中,其中在耦合值,但...如果你不能添加AUTO_INCREMENT ...

set @m:=(select max(userByStock) from table3); insert into table3 (stockId, userId, userByStock) select table1.stockId, table2.userId, (@m := @m + 1) from table1 cross join table2; 

And ...完整的解决方案将是:

set @m:=(select max(userByStock) from table3); insert into table3 (stockId, userId, userByStock) select table1.stockId, table2.userId, (@m := @m + 1) from table1 cross join table2 where not exists(select * from table3 as t3 where t3.stockId = table1.stockId and t3.userId = table2.userId); 
+0

我也会尝试这个,事情是递增必须找到表3中已经存在的最高值,然后总是+ 1该值 – MJ95

+0

这已经通过auto_increment – mlattari

+0

完成是的,但我不能让列表3中的自动增量列,我是“不允许”操纵,我只能插入或从 – MJ95

0

我会考虑简单地做一个INSERT IGNORE,假设你在连接表的stockID和userID字段中有唯一的索引。

INSERT IGNORE INTO table3 (stockID, userID) 
SELECT table1.stockID, table2.userID 
FROM table1 CROSS JOIN table2 

这将尝试插入笛卡尔(交叉)的Table 1和Table加入到表3,忽略其中stockID和用户ID的唯一索引已经存在的所有行。

假设你的userByStock字段是一个自动增量字段,插入到该字段的值将自动递增。

如果您认为需要添加到表3的行数表示表1和表2中行组合的重要百分比,那么这可能是一个很好的解决方案。如果你只有一行或两行添加到表3中,并且表3有很多行,那么这个解决方案可能不会像专门识别必要的插入那样最优化,因为你本质上会做一堆插入忽略。

+0

谢谢,它不是自动增量字段,我必须自己增加它,我卡在 – MJ95

+0

@ mj95为什么不把它作为自动增量字段?这就是他们打算用于 - 给你一系列递增独特的ID –

+0

我不能操纵该表的实体,只能插入它(这是一个官僚主义的东西) – MJ95