我有一个丑陋的SQL Server 2014表,其中包含书籍。每本书都可以由多位作者撰写,因此一本书可以在表格中重复多次,每位作者一行。 ISBN字段唯一标识该书。
数据看起来像这样:
TABLE NAME = "OldUglyTable"
ID ISBN BookTitle AuthorName
1 1 My Awesome Book John Smith
2 1 My Awesome Book Sally Johnson
3 2 All About Cats Frank Jones
4 1 My Awesome Book A. Smithfield
我们现在所做的是创建了两个新的空表Books
(自动递增BookID
,ISBN
(唯一键)和BookTitle
)和{{ 1}}(自动递增BookAuthors
,ID
(FK到BookID
),Books
)。最初的AuthorName
字段是垃圾,我们并不关心它。
我无法更改表结构,但是我试图通过在ID
表中为每个唯一ISBN
创建一条记录来快速将记录移动到这两个表中,然后为每个作者创建一条记录在Books
表格中,其中FK输出到BookAuthors
字段Books
上刚刚创建的新记录。
如何有效地将这些数据拆分到这两个新表中,并将FK插入BookID
?
我有超过6000万行!我尝试在ISBN上进行行号分区并从CTE获取第一行,因为BookAuthors
并不总是返回正确的数据,但这甚至给了我
SSMS中的' System.OutOfMemoryExceptionSystem.OutOfMemoryException'
错误。 :(我不确定最好的方法是什么。
答案 0 :(得分:1)
首先,使用此查询将INSERT
个不同的书籍放入Books
表:
INSERT INTO Books(ISBN, BookTitle)
SELECT DISTINCT
ISBN, BookTitle
FROM OldUglyTable
然后,INSERT
作者BookAuthor
使用INNER JOIN
:
INSERT INTO BookAuthors(BookID, AuthorName)
SELECT
b.BookID, t.AuthorName
FROM OldUglyTable t
INNER JOIN Books b
ON b.ISBN = t.ISBN
为了帮助提高性能,我建议您在Books
表中插入后创建这两个索引:
CREATE NONCLUSTERED INDEX IXN_Books_ISBN ON Books(ISBN)
CREATE NONCLUSTERED INDEX IXN_OldUglyTable_ISBN ON OldUglyTable(ISBN) INCLUDE(AuthorName)