为新表插入行,覆盖TableA和TableB中ID列的组合

时间:2016-10-28 02:33:03

标签: sql-server tsql

现有两个表,我想用现有表中的ID列组合填充一个新表(让我们称之为MiddleTable)。这是我的表结构(简化),而不是IntField在插入时很重要我希望这是一个特定的值,然后可以以与此问题无关的方式进行更改。

表A

ID, Other columns

表B

ID, Other columns

MiddleTable

TableA_ID, TableB_ID, IntField, Other columns ....

我的解决方案是这样的,是否有更简单的方法或没有一些重要缺点的方法?

INSERT INTO MiddleTable (TableA_ID, IntField, TableB_ID) 
  SELECT 
      X.TabAID, 0, X.TabBID 
  FROM 
      (SELECT 
           TableA.ID AS TabA_ID, TableB.ID AS TabB_ID 
       FROM 
           TableA, TableB
       EXCEPT 
       SELECT 
           TableA_ID, TableB_ID  
       FROM 
           MiddleTable) X

2 个答案:

答案 0 :(得分:2)

INSERT INTO Main_Table(TabA_ID,TabB_ID)
SELECT Table_A.ID,Table_B.ID FROM Table_A CROSS JOIN Table_B 
EXCEPT 
SELECT TabA_ID,TabB_ID FROM Main_Table

答案 1 :(得分:1)

这将是等效的,对于SQL Server来说,效率更高。也就是说,如果您在MiddleTable中有一个INDEX,其ID_A, ID_B列用于快速查找。

它还使用显式CROSS JOIN代替FROM TableA, TableB的隐式交叉连接。正如@marc_s已经指出的那样,隐式语法是旧学的,不推荐使用,可能会在SQL Server的未来版本中删除。

CREATE TABLE #TableA(ID INT, Other NVARCHAR(128));
CREATE TABLE #TableB(ID INT, Other NVARCHAR(128));
CREATE TABLE #Middle(ID_A INT, ID_B INT, intfield INT, Other NVARCHAR(128));
ALTER TABLE -- index for fast lookup
    #Middle
ADD CONSTRAINT 
    PK_middle PRIMARY KEY CLUSTERED (ID_A,ID_B);

INSERT INTO #Middle(ID_A,ID_B,intfield)
SELECT
    A.ID,B.ID,0
FROM
    #TableA AS A
    CROSS JOIN #TableB AS B
WHERE
    NOT EXISTS(
        SELECT 1
        FROM #Middle AS m
        WHERE m.ID_A=A.ID AND m.ID_B=B.ID
    );

NOT EXISTS条件将执行左反半连接以查看现有行,以便不再插入这些行。对于SQL Server来说,这通常是更有效的方式。