2011-02-11 42 views
5

我想将现有的表格转换为第一范式(可能的最简单的标准化;请参阅示例)。什么是T-SQL规范化现有的表?

你碰巧知道什么是T-SQL是这样的问题?非常感谢!

enter image description here

更新

尝试下面的答案,它的工作完美。以下是我用来测试答案的步骤:

  1. 启动Microsoft SQL Management Studio。
  2. 用下面的数据创建表格。
  3. 确保“客户”中的ID设置为“主键”和“身份”。
  4. 确保“订单”中的ID没有特殊设置(其外键)。
  5. 打开数据库图表,然后在“客户”和“订单”表之间创建1:*关系。
  6. 在“客户”表格和“订单”表格上执行脚本,它会自动正确地为您正常化数据。
  7. 如果您从刚刚导入的平面.csv文件开始,并且希望将信息复制到数据库中的规范化表单,这非常有用。
+0

您的图片链接无法正常工作。 – 2011-02-11 17:46:19

+0

我同意这是一个合理的重构,但它不是标准化。没有什么功能上依赖于`name`。 – 2011-02-11 17:52:28

+0

我承认这是一个玩具的例子来问这个问题 - 与此相比,完整的问题有点复杂。 – Contango 2011-02-11 18:03:47

回答

4

与客户表

INSERT INTO Customer (Name) 
SELECT DISTINCT Name 
FROM Flat_CSV_File 

开始如果您有反复进口

INSERT INTO Customer (Name) 
SELECT DISTINCT f.Name 
FROM Flat_CSV_File f 
LEFT OUTER JOIN Customer c ON f.Name = c.Name 
WHERE c.Id IS NULL 

订单(您的表名称Order是TSQL中的保留字,所以您需要用方括号引用它)

INSERT INTO [Order] (CustomerId, Description, Cost) 
SELECT c.Id, f.Description, f.Cost 
FROM Flat_CSV_File f 
INNER JOIN Customer c ON f.Name = c.Name 
0

如果这是一次性过程,我会先操作.csv,然后在那里形成包含主键的表。当您填充SQL数据库,使用

SET IDENTITY_INSERT Customers ON 

INSERT Customers 
(
    ... 
) 
SELECT 
    ... 
FROM 
    openrowset(...) 

SET IDENTITY_INSERT Customers ON 



SET IDENTITY_INSERT Orders ON 

INSERT Orders 
(
    ... 
) 
SELECT 
    ... 
FROM 
    openrowset(...) 

SET IDENTITY_INSERT Orders ON 

如果你需要一个纯粹的TSQL的解决方案,我将创建临时表做同样的基本的东西,并从临时表,而不是插入的.csv。

+0

没有理由做一个你打开和关闭身份插入的过程。这不是一个好习惯。 – HLGEM 2011-02-11 17:56:41

4

最简单的解决方法就是编写一个查询做进口:

-- assuming that Id is an Identity column or has some default to generate keys. 
Insert Customer([Name]) 
Select Name 
From Flat_csv_file 
Group By Name 

Insert Order([Customer], [Description], Cost) 
Select C.Id, F.Description F.Cost 
From Customer As C 
    Join Flat_csv_file As F 
     On F.Name = C.Name 
+0

不错!我现在就试试这个。 – Contango 2011-02-11 17:57:10

4

在上述情况下,@Thomas有一个完美可行的解决方案。然而,有时候人们为了提出问题而简化,所以我会解释如果您需要去多个表(或者第一个表没有唯一的名称限制),您可能会想要做什么,而不仅仅是二。

首先,我会将数据插入登台表并添加一个id为空的列。然后,我会使用OUTPUT子句向父表写入插入操作,以将ID和自然键输出到表变量。然后,我会使用表变量来更新登台表中的id字段。然后我会将登台表中的记录插入到其他表中。因为我现在有了id,所以不再需要访问原始父表。 (如果记录的数量很大,我也可以为登台表编制索引)。

现在,如果您没有自然键,则该过程变得更加困难,因为您无法确定哪条记录会发送给谁。然后,我通常为登台表添加一个身份,然后一次向父表进行一次初始导入(包括作为游标中的变量的stagingtableid),然后使用每个父表id尽快更新登台表创建。一旦所有的初始记录被更新,我使用基于集合的过程插入或更新到其他表。

临时表还可以让您在试图将其放入生产表之前修复任何不良数据的机会。

如果事情很复杂或者这是一个重复的过程,您可能需要知道的其他语法是MERGE语句。如果它是新记录,则会插入,如果它是现有记录,则进行更新。

如果这是一个非常复杂的转换,您可以考虑使用SSIS。