【问题标题】:How to: select and insert parent child records without using loop in sql如何:在 sql 中不使用循环选择和插入父子记录
【发布时间】:2016-05-13 15:06:03
【问题描述】:

我有两张桌子

OrderedStock
---
OrderID    Location
1          Richmond
2          Ohio
3          Queens


OrderItem
---
OrderItemID  OrderID   Name
1            1         Perfume
2            1         Blinds
3            2         Ball
4            3         Cabinet

如果我必须将这些表中的所有记录复制到类似的表(PostedOrder 和 PostedOrderItem)中,最好的方法是在 PostedOrderItem 表中保留正确的 PostedOrderId。实际上,我在 Order 表中有大约 45K 行要复制,它们嵌套的 OrderItem 记录大约是 200 万。

目标表及其数据如下所示

PostedOrdered
---
PostedOrderID    Location
11               Richmond
12               Ohio
13               Queens


PostedOrderItem
---
PostedOrderItemID  PostedOrderID       Name
101                11                  Perfume
102                11                  Blinds
103                12                  Ball
104                13                  Cabinet

PostedOrderId 和 PostedOrderItemId 是各自表中自动递增的主键。

我应该遵循什么最好的方法,而不用选择satement彻底循环?

提前感谢并为激烈的格式道歉。

【问题讨论】:

  • 这个问题不清楚。为什么需要循环才能将记录插入新表? SQL INSERT 可以解决问题。无需循环。
  • “相似表”是什么意思?什么是“订单表”,你只有OrderedStockOrderItem?您是否尝试从OrderedStock 获取行并将它们放入OrderItem?或者尝试从OrderItem 中取出行并将它们放入OrderedStock?或者试图从这两个表中取出行并将它们放入另一个表中?请显示您想要的结果的一些示例输出。
  • Devlin:我必须将 OrderStock 和 OrderItemTable 分别复制到 PostedOrder 和 PostedOrderItem 表中。源表是 1. OrderStock 2. OrderItem 目标表是 1. PostedOrder 2. PostedOrderItem 希望它能澄清问题 Paul
  • 您使用的是哪个 DBMS?后格雷斯?甲骨文?

标签: sql select insert parent-child


【解决方案1】:

在您的已发布订单表中,您还需要包含一个“原始 ID”列。您还没有指定如何生成新的 id,所以我假设它是一个 INT IDENTITY(1,1) 列。

PostedOrder 的示例表架构:

PostedOrderID INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
Location VARCHAR(100),
OriginalID INT NOT NULL  /* This is the id from the original table  */

在此表中插入记录:

INSERT INTO PostedOrder (Location,OriginalID)
SELECT Location, OrderID FROM OrderedStock

然后,您可以使用原始 ID 作为链接,为 PostedOrderItem 表获取新的 PostedOrderID

PostedOrderItem 的示例表架构:

PostedOrderItemID INT IDENTITY(1,1) PRIMARY KEY NOT NULL,
PostedOrderID INT NOT NULL, /* foreign key to PostedOrder table */
Name VARCHAR(100)

注意:如果出于任何原因您需要保留 items 表的原始 id,您也可以为此添加一列。您的插入不需要它。

将记录插入PostedOrderItem:

INSERT INTO PostedOrderItem (PostedOrderID, Name)
SELECT p.PostedOrderID, o.Name
FROM PostedOrder p
INNER JOIN OrderItem o ON o.OrderID = p.OriginalID

【讨论】:

  • 我不需要原始ID。 PostedOrderId 和 PostedOrderItemId 都是 identity(1,1) 列。如果您查看我的原始问题(我最近更新)中的目标结果,您可能会更好地了解我所追求的。
  • 我只需要从源中复制一些订单并将它们保存到新的 Posted 表中(当然还有它们的正确项目)
  • @AliRaza - 您确实需要 PostedOrder 表中 OrderedStock 表中的原始 id,因为它是获取 PostedOrderItem 表中 PostedOrderID 的一种方式。插入记录后,您可以根据需要从 PostedOrder 中删除原始 id 列。
  • 得到了线索 - 肯定会尝试,但仍在寻找一个解决方案,我可以避免在最后删除一列。感谢您的帮助。
  • 根据我的经验,这是最简单的方法。您有 2 个查询和一个可选的列删除。当我完成类似的数据迁移时,我将原始 id 列保留了一段时间,以防对新记录与旧记录之间的关系有任何疑问。这为您提供了跟踪任何问题的内置路径。
【解决方案2】:

您可以使用两个基于数据透视表的插入选择

insert into aTempTable (OrderItemID, OrderID, Name, Location) 
select a.OrderItemID,  a.OrderID,   a.Name,  b.Location 
from OrderItem as a 
inner join OrderedStock as b on a.OrderID = b.OrderID;


insert into  PostedOrder (OrderID, Location) 
select distinct OrderID, Location 
from aTempTable ;


insert into PostedOrderItem (OrderItemID, OrderID, Name) 
select OrderItemID,  OrderID,   Name
from aTempTable ;

如果您需要新的 OrderItemID,请使用此

insert into aTempTable ( OrderID, Name, Location) 
select    a.OrderID,   a.Name,  b.Location 
from OrderItem as a 
inner join OrderedStock as b on a.OrderID = b.OrderID;


insert into  PostedOrder (OrderID, Location) 
select distinct OrderID, Location 
from aTempTable ;


insert into PostedOrderItem ( OrderItemID, OrderID, Name) 
select OrderItemID,  OrderID,   Name
from aTempTable ;

【讨论】:

  • 这样我会将旧的/原始的 OrderId(来自 OrderItem)插入 PostedOrderItem 表。在 PostedOrderItem 中,我需要新生成的 (PostedOrderId) 作为 parentId
  • 我已经进一步阐述了这个问题。希望现在更清楚。
  • 感谢您的建议,但它没有用,因为第一个插入语句正在 PostedOrder 表中插入重复的订单。我所追求的是一种按订单选择,然后将其插入 PostedOrder,获取 newIdentity 并将其与所有嵌套项一起附加,同时将其插入 PostedOrderItem。
  • hmm 但插入 PostedOrderItem 再次从 OrderStock 中选择 OrderId 而不是 PostedOrder 中生成的新 Id :(
  • 如果你需要新的 itemOrderId ...我已经更新了答案
猜你喜欢
  • 1970-01-01
  • 2014-08-05
  • 1970-01-01
  • 2016-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-24
  • 2012-02-26
相关资源
最近更新 更多