【问题标题】:How do I insert data from one table to another when there is unequal number of rows in one another?当另一个表中的行数不相等时,如何将数据从一个表插入到另一个表中?
【发布时间】:2019-03-25 23:07:08
【问题描述】:

我有一个名为 People 的表,它有 19370 行,playerID 是主列。还有一个名为Batting 的表,它以playerID 作为外键,有104324 行。

有人告诉我在People 表中添加一个名为Total_HR 的新列,该列包含在Batting 表中。所以,我必须将Batting 表中的列数据插入People 表中。

但是,我得到了错误:

消息 515,级别 16,状态 2,第 183 行无法将值 NULL 插入 列'playerID',表'Spring_2019_BaseBall.dbo.People';柱子 不允许空值。插入失败。声明已终止。

我尝试了UPDATEINSERT INTO SELECT,但是得到了同样的错误

insert into People (Total_HR)
select sum(HR) from Batting group by playerID

我希望输出使用Batting 表中的HR 列填充People 表中的Total_HR 列。

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    你可以使用连接

    BEGIN TRAN
    
    Update  People
    Set     Total_HR = B.HR_SUM
    from    PEOPLE              A   
        left outer join
            (Select playerID, sum(HR) HR_SUM 
            from Batting 
            group by playerID)  B   on A.playerID = B.playerID
    
    Select * from People
    
    ROLLBACK
    

    请注意,我已将此代码放入事务块中,以便您可以在提交之前测试更改

    【讨论】:

    • 我是否添加关键字“commit”来代替“rollback”,因为这确实有效
    【解决方案2】:

    从错误消息看来,playerID 似乎是 People 表中的必填字段。 您需要在 INSERT INTO 子句中指定 People 表的所有必填字段,并在 SELECT 子句中提供相应的值。

    我在下面添加了字段 playerID,但您可能还需要添加其他必填字段。

    insert into People (playerID, Total_HR)
    select playerID, sum(HR) from Batting group by playerID
    

    然而,奇怪的是,您想在应该已经存在的表中插入行。否则,您无法在 Batting 表中的字段 playerID 上拥有有效的外键...如果您尝试将此类行从表 Batting 插入到表 People 中,您可能会收到另一个错误(违反 PRIMARY KEY 约束)...除非。 ..您刚才正在创建数据库,并且您想在将实际外键约束添加到表 People 之前从填充/导入的表 Batting 填充空表 People。对不起,我不会质疑你的意图。我个人会考虑稍微更新查询,以便它不会尝试插入表 People 中已经存在的任何行:

    insert into People (playerID, Total_HR)
    select Batting.playerID, sum(Batting.HR)
    from Batting
    left join People on People.playerID = Batting.playerID
    where People.playerID is null and Batting.playerID is not null
    group by playerID
    

    【讨论】:

      【解决方案3】:

      您需要计算SUM,然后将此结果连接到People 表,以将People 中的Total_HR 列和Batting 中计算的相应SUM 放入相同的行中。

      这是一种写法。我用 CTE 使可读性更强。

      WITH
      CTE_Sum
      AS
      (
          SELECT
              Batting.playerID
              ,SUM(Batting.HR) AS TotalHR_Src
          FROM
              Batting
          GROUP BY
              Batting.playerID
      )
      ,CTE_Update
      AS
      (
          SELECT
              People.playerID
              ,People.Total_HR
              ,CTE_Sum.TotalHR_Src
          FROM
              CTE_Sum
              INNER JOIN People ON People.playerID = CTE_Sum.playerID
      )
      UPDATE CTE_Update
      SET 
          Total_HR = TotalHR_Src
      ;
      

      【讨论】:

        猜你喜欢
        • 2014-10-15
        • 1970-01-01
        • 2020-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-25
        相关资源
        最近更新 更多