2016-06-21 65 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

相關問題