【问题标题】:SQL: Normalizing Code / Export - ImportSQL:规范化代码/导出 - 导入
【发布时间】:2011-03-17 00:04:03
【问题描述】:

我决定重写我拥有的规范化很差的数据库。我已经创建了新数据库,但现在需要将数据从旧数据库移到新数据库中。我不确定如何完成。例如,在旧数据库中,我有一个如下所示的 webDorms 表:

id (PK, int)
room_type (varchar) 
description (char) 
available (varchar) 
max_occupancy (varchar) 
current_occupancy (varchar) 
dorm_room (varchar) 
dorm_building (varchar) 
building_code (varchar) 

在新数据库中,我将其拆分为两个表 Buildings 和 Housing。住房是这样的:

id (PK, int) 
building (FK, int) 
room (nvarchar)
current_occupancy (int) 
max_occupancy (int) 
is_available (bit) 
gender (nvarchar) 
room_type (nvarchar)

建筑物看起来像这样:

id (PK, int) 
building_code (nvarchar) 
building_name (nvarchar)

我手动重新填充了 Buildings 表(大约有 20 行),但 Housing 表(与之前的 webDorms 表最相似)包含大约 300 行 - 我宁愿不重新输入所有数据。

对完成此导入的最佳方式有何建议?

【问题讨论】:

  • 新表是在同一个数据库中,还是在单独的数据库中?如果它们位于不同的数据库中,有什么方法可以在它们之间使用 SELECT/INSERT 语句?
  • 它们位于不同的数据库中 - 我可以使用 SELECT/INSERT 并考虑使用 SELECT INTO - 但我需要一种方法来跳过某些列(在目标表中)并将字符串转换为相关的 ID 号(例如 building_name 到建筑物)

标签: sql sql-server tsql import export


【解决方案1】:

如果我在您的问题中遗漏了一些明显的内容,请在评论中告诉我,但是使用 INSERT 查询复制数据而不是重新输入数据有什么问题?

【讨论】:

  • 你能给我一个我可以如何做到这一点的样本吗?最大的难题是在一些旧列中数据是字符串,但在新表中它需要是整数(ID)。我需要在导入期间执行该转换。
  • 在查询中使用 CAST 或 CONVERT 关键字将数据转换为正确的格式。例如 CAST(StringValueField as INT)
  • Tbe 值不是从字符串到整数的严格转换。相反,现在存在另一个表,其中包含与每个建筑物相关的 ID。
  • 诀窍是在原始表中添加一列并用新的建筑物 ID 填充它,然后您应该能够在同一个 INSERT INTO 查询中传输住房数据。
  • 呃。 :) 当答案如此简单时,有时我会觉得自己很愚蠢!
【解决方案2】:

这是 SQL 具有 SELECT DISTINCT 的原因之一——规范化。

来自源表的两个 SELECT DISTINCT 查询应创建生成的两个规范化表。

你有两种方法。

INSERT INTO new_table_1(...) AS SELECT DISTINCT a, b, c FROM old table
INSERT INTO new_table_2(...) AS SELECT DISTINCT d, e, f FROM old table

或执行两个单独的查询以创建两个单独的提取文件(CSV 格式)。然后加载这两个文件。

【讨论】:

  • 这看起来不错...如何将字符串数据转换为整数 (ID) 数据?
  • @davemackey:字符串到整数。你有 SQL 参考吗?检查那个。数据转换几乎总是自动进行的。
【解决方案3】:

你会想做这样的事情:

SELECT CAST(current_occupancy AS int) AS current_occupancy,
       CAST(max_occupancy AS int) AS max_occupancy,
       CAST(available AS bit) AS available

您需要查看在线书籍,特别是CAST and CONVERT

您提到规范化是重新设计表格的原因,但您尚未规范化所有可能性。房间类型和性别是这里的候选者,最大和当前入住人数的数据类型也相当大,除非您想要拥有可容纳 20 亿人的房间。 :0)

【讨论】:

  • 是的,我考虑过规范房间类型和性别 - 但这会带来比我目前所能证明的更多的工作,而实际收益很少或根本没有。
【解决方案4】:

它看起来像这样:

INSERT INTO ['database'].dbo.[housing] (id, building, current_occupancy, max_occupancy, room_type, is_available)
  SELECT id, [building].id, cast(current_occupancy as int), cast(max_occupancy as int), room_type, CASE available WHEN 'Y' THEN 1 ELSE 0 END)
  FROM ['database'].dbo.[webDorms]
  INNER JOIN ['database'].dbo.[building] ON [building].building_code = [webDorms].building_code

[Room] 和 [Gender] 需要手动添加,或者您可以在插入期间使用默认值填充它们。

这当然是在您填充了 [building] 表之后,这可以通过以下方式完成:

INSERT INTO ['database'].dbo.[building] (building_code)
  SELECT DISTINCT building_code 
  FROM ['database'].dbo.[webDorms] 

然后手动填充您的 [building_name](而不是键入所有数据)。

【讨论】:

  • 谢谢,这很有帮助。尽管显然您不能将 Y/N 投射到 bit 上。 :( 但我会在旧表中添加另一列并手动进行转换...
  • 您可以将其包装在一个盒子中,并将结果分别设置为 1 或 0(以避免必须手动执行)。我修改了我的帖子以反映这一点。
  • 谢谢瑞克。我最终通过添加另一列来做到这一点 - 但这并不难 - 我会记住案例方法以供将来参考。
猜你喜欢
  • 2012-02-04
  • 1970-01-01
  • 2010-11-10
  • 1970-01-01
  • 2011-09-11
  • 1970-01-01
  • 1970-01-01
  • 2011-06-19
  • 1970-01-01
相关资源
最近更新 更多