【问题标题】:Insert into Table using multiple columns使用多列插入表格
【发布时间】:2018-10-09 11:47:01
【问题描述】:

假设我们有一个如下所示的表:

Comma1 列是 personID 值,comma2comma3comma4 等(此表是动态创建的,因此可以超过 4 列)是 teamID。

现在,我有另一个名为personTeam 的表,它保持personidsteamids 之间的关系。例如,如果人员 13 是团队 3 和团队 8 的成员,那么 personTeam 表中应该有 2 条记录(13,3 和 13,8)。

我需要的是,使用附图中的这个表,将personidsteams 插入到PersonTeam 表中。例如,对于 149 人,我想要插入 (149,10),但对于 221 人,我想要 (221,7)、(221,8)、(221,11)。

有没有办法解决这个问题? 谢谢

【问题讨论】:

    标签: sql sql-server insert


    【解决方案1】:

    解决这个问题的一种方法是使用UNIONUNION ALL

    例如:

    insert into personTeam (personid, teamid)
    select comma1 as personid, comma2 as teamid
    from commastable
    where comma2 is not null
    union
    select comma1, comma3
    from commastable
    where comma3 is not null
    union
    select comma1, comma4
    from commastable
    where comma4 is not null;
    

    UNION 只会返回唯一的记录,但要做到这一点,它必须对结果进行排序。这可能会使它比 UNION ALL 稍微慢一些,后者只会将联合查询的结果粘在一起。
    我希望源数据不包含重复项,因此 UNION 仅用于确保它仅插入唯一的元组。

    如果你想让这个可重复?
    只需将该查询放在子查询中,然后将其加入 personTeam 即可。

    insert into personTeam (personid, teamid)
    select q.personid, q.teamid
    from
    (
      -- add the query with the unions here
    ) as q
    left join personTeam as t 
      on (t.personid = q.personid and t.teamid = q.teamid)
    where t.personid is null;
    

    【讨论】:

      【解决方案2】:

      您正在 SELECT 语句中寻找 UNPIVOT 子句。

      测试数据

      declare @t1 as table (
          comma1 int,
          comma2 int,
          comma3 int,
          comma4 int 
      )
      
      insert into @t1 values
           (149,10,null,null)
          ,(221, 7,8,11)
          ,(278,3,10,null);
      
      select * from @t1;
      

      解决方案示例

      select comma1 as personid , value1
      into #TmpTeam
      from @t1 unpivot ( value1 for Team in ( comma2,comma3,comma4)) as p;
      
      select * from #TmpTeam;
      

      您可以使用其他语法将查询结果插入到您的表中。这只是一个例子。

      【讨论】:

      • 您好,unpivot 听起来确实不错,但正如我上面提到的,此表是动态创建的,因此它可能有 5 列而不是 4 列。在这种情况下,我需要也是动态的 unpivot。正确吗?
      【解决方案3】:

      要让它处理任意数量的列,您可以构建一个动态查询并执行它。

      DECLARE @dynSql VARCHAR(max)
      DECLARE @table_name VARCHAR(max) = 'tbl'
      
      SELECT @dynSql = (
        SELECT 
           'INSERT INTO personTeam SELECT comma1, ' + 
            COLUMN_NAME + 
           ' FROM ' + 
           @table_name + 
           ' WHERE ' + 
           COLUMN_NAME + 
           ' IS NOT NULL; '
        FROM INFORMATION_SCHEMA.COLUMNS
        WHERE TABLE_NAME = @table_name
        AND ORDINAL_POSITION != 1
        FOR XML PATH('')
      )
      
      EXECUTE(@dynSql);
      
      SELECT * FROM personTeam
      

      只需将@table_name 变量设置为输入表的名称即可。

      它的作用是构建一个这样的字符串

      INSERT INTO personTeam SELECT comma1, comma2 FROM tbl WHERE comma2 IS NOT NULL;
      

      对于输入表中的每一列(第一列除外;即 comma2、comma3、...),然后执行该语句。

      http://sqlfiddle.com/#!18/53fcd/24

      【讨论】:

        【解决方案4】:

        如果我是一次性完成,我会简单地做三个插入。

        INSERT INTO personTeam (personids, teamids)
        SELECT comma1, comma2 from table
        
        SELECT comma1, comma3 from table WHERE comma2 is null
        
        INSERT INTO personTeam (personids, teamids)
        SELECT comma1, comma4 from table WHERE comma2 is null and comma3 is null
        

        unpivot 命令用于将数据标准化为表格。它仅适用于 2005 年以上

        select comma1, teamids
        from input
        unpivot
        (
          teamids
          for teams in (comma2, comma3, comma4)
        ) as u;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-25
          • 1970-01-01
          相关资源
          最近更新 更多