我想将现有表格转换为第一范式(最简单的规范化;参见示例)。
你碰巧知道T-SQL是针对这类问题的吗?非常感谢!
更新
尝试下面的答案,它运作得很好。以下是我用来测试答案的步骤:
答案 0 :(得分:5)
在上面的案例中,@ Thomas有一个非常可行的解决方案。但是,有时人们为了提出问题而简化,所以如果你需要去多个表(或者第一个表对名称没有唯一约束),我会解决你可能想做的事情,而不仅仅是2。
首先,我将数据插入到临时表中,并为id添加一列为null。然后我将使用OUTPUT子句向父表写入一个插入,以将id和自然键输出到表变量。然后我将使用表变量来更新登台表中的id字段。然后我会将登台表中的记录插入到其他表中。由于我现在拥有id,因此不再需要访问原始父表。 (如果记录数量很大,我也可以索引登台表。)
现在如果你没有自然键,那么这个过程会变得更难,因为你无法识别哪个记录归谁所有。然后我通常会在登台表中添加一个标识,然后一次向父表导入一个记录(包括stagingtableid作为游标中的变量),然后用每个父表id更新登台表,因为它是创建。更新所有初始记录后,我使用基于集合的进程插入或更新到其他表。
临时表还使您有机会在尝试将其放入生产表之前在本地修复任何错误数据。
如果事情很复杂或者这是一个重复的过程,您可能需要知道的其他语法是MERGE语句。如果是新记录,则插入,如果是现有记录则更新。
如果这是一个非常复杂的转换,您可以考虑使用SSIS。
答案 1 :(得分: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
答案 2 :(得分:4)
从Customer表开始
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
订单(您的表名称顺序是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
答案 3 :(得分: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中插入。