【问题标题】:What's the cleanest way in SQL to break a table into two tables?SQL中将一个表分成两个表的最干净的方法是什么?
【发布时间】:2021-07-09 01:25:33
【问题描述】:

我有一张桌子,我想分成 2 张桌子。我想从A表中取出一些数据,放到一个新的B表中,然后将A中的每条记录指向新表中对应的记录。

用 INSERT INTO B blah blah SELECT blah blah FROM A 填充新表很容易。但问题是,当我在 B 中创建新记录时,我想将 B 记录的 ID 写回A.

我想到了两种方法:

  1. 创建一个游标,一次遍历 A 一条记录,在 B 中创建记录并将新 ID 发送回 A。

  2. 使用提取的数据、新记录的 ID 和 A 的 ID 创建一个临时表。然后使用此临时表填充 B 并将 ID 发送回 A。

这两种方法看起来都很麻烦,需要来回复制大量数据。有没有一种干净、简单的方法可以做到这一点,还是我应该硬着头皮努力去做?

哦,我正在使用 Microsoft SQL Server,如果您的答案取决于 SQL 的非标准功能。

有人要求举个例子。是的,我应该包括一些具体的东西来说明清楚。真实的例子是一堆数据,但让我举一个简化的例子来说明我的意思。

假设我有一个包含 customer_id、name 和 city 的 Customer 表。我想把 city 分成一个单独的表。

例如:

Customer
ID  Name     City
17  Al       Detroit
22  Betty    Baltimore
39  Charles  Cleveland

我想把它转换成:

Customer
ID  Name    City_ID
17  Al      1
22  Betty   2
39  Charles 3

City
ID  Name
1   Detroit
2   Baltimore
3   Cleveland

确切的 ID 值无关紧要。

创建 City 表和引用非常容易......

create table city (id int identity primary key, name varchar(50))
alter table customer add city_id int references city

然后填充城市表...

insert into city (name)
select city from customer

诀窍在于如何将这些城市 ID 恢复到 Customer 表中。

(是的,在这个简化的示例中,努力可能看起来毫无意义。在现实生活中,我们有许多带有地址的表,我想从所有其他表中提取所有这些字段并将它们放入一个地址表中,所以我们可以标准化地址的声明和处理。)

(注意:上面的示例代码我没有测试过。如果有错别字,请见谅。)

【问题讨论】:

  • 请提供样本数据和期望的结果。
  • 您如何关联您的数据,tableB 是否有自己的identity 值,您是否为 TableB.Id 向 tableA 添加一列?
  • 两张表之间的基数/关系是什么?一对一?如果是这样,你不需要“写一个 ID”,但你也不需要一个身份列。
  • @stu 是的,我将 tableB.id 发布到表 A 中。
  • @SMor 在现实生活中会有多个表都指向表B。所以A、C、D等都会有一个指向B的指针。练习的原因是因为我们有许多不同表中的地址,当然,它们都有不同的格式和不同的处理方式。我想将所有地址拉到一个地址表中,以便我们将它们标准化。

标签: sql-server tsql


【解决方案1】:

您可以使用output 子句来捕获您的新 ID 值。

没有任何示例数据或您正在执行的示例,以下只是一个指南。

创建一个#table 来保存新的 ID 值,然后插入新插入的 Id 标识值以及来自inserted 虚拟表的相关值。然后,您可以通过加入此相关值来使用新 ID 更新原始表。

create table #NewIds (TableBId int, TableAId int)

insert into TableB (column list)
output inserted.Id, inserted.TableAId into #NewIds
select column list
from TableA

update a
set a.TableBId=Id
from #NewIds n join TableA a on a.Id=n.TableAId

【讨论】:

  • 这看起来非常接近,但据我所知,有一个问题。 OUTPUT 子句只能引用插入到表中的字段。因此,除非我在表 B 中包含表 A 中的 ID,否则这似乎不起作用。我不希望指针双向使用,因为这会造成潜在的数据不一致。好吧,我可以将指针从 B 添加到 A,然后在插入后将其删除。或者,还有更好的方法?感谢您的帮助!
  • @jay 好的,有一个解决方法 - 我没有太多工作要做,但另一种方法是使用merge,您可以访问所有相关人员的列表。我目前没有时间,但会在适当的时候重构我的答案;如果您还需要帮助,请尝试一下。
  • 这不是一个完整的最终答案,但它很有帮助。 (我投了赞成票,所以你会得到一些荣耀和荣誉!)我会考虑合并。现在,我正在添加额外的字段,以便稍后删除它。在这种情况下,这不是一个大问题,因为我计划稍后从原始表中删除这些字段,所以这只是一次清理工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 2010-12-23
相关资源
最近更新 更多