从单个非规范化表创建规范化表
Posted
技术标签:
【中文标题】从单个非规范化表创建规范化表【英文标题】:Creating normalized tables from a single de-normalized table 【发布时间】:2015-07-15 19:06:33 【问题描述】:好的,请耐心等待,我会尽可能清楚地解释这一点。
我有一个来自 dBASE 的旧数据表,目前在 SQL 中,我需要将其分解为规范化表。旧表包含 LastName、FirstName、SSN、TestDate、Score、TestDate2、Score2、TestDate3、Score3 的列。当使用旧系统时,操作员需要添加额外的测试,他们必须创建一个具有相同姓氏、名字、SSN 的全新记录才能进入第四次测试,因为每条记录只有三个考试的位置。新数据库有一个用于 LastName、FirstName 和 SSN 的员工表,以及一个用于每个考试的测试表。我不知道如何编写程序来获取员工的唯一实例以及所有测试记录,当它有不止一行关联时。
这是数据的“示例”...
一个正确方向的点将是一个巨大的帮助!谢谢!!
编辑:SQL Server 2012,Employee 表当前有一个 EmployeeId,它将用作 IDENTITY 字段。 Exam 表将 EmployeeId 作为 FK。
【问题讨论】:
什么版本的 SQL Server?新表的结构是什么?它现在有 EmployeeId 吗?那是身份吗? 抱歉,Martin,我已经编辑了 OP 来回答这些问题。 在您的重组中,您还应该停止以纯文本形式存储 SSN。它应该被加密。 我没有以纯文本形式存储 SSN,它在初始加载时通过应用服务器加密。这只是示例数据。 我了解示例数据。当我看到纯文本的 SSN 时,这让我感到畏缩。 :) 【参考方案1】:你可以使用类似下面的东西
INSERT INTO Employee
(LastName,
FirstName,
SSN)
SELECT DISTINCT LastName,
FirstName,
SSN
FROM Denormalised
INSERT INTO Test
(EmployeeId,
TestDate,
TestScore)
SELECT E.EmployeeId,
CA.TestDate,
CA.TestScore
FROM Denormalised D
JOIN Employee E
ON EXISTS(SELECT E.LastName,
E.FirstName,
E.SSN
INTERSECT /*Null safe equality in case any of the columns are nullable*/
SELECT D.LastName,
D.FirstName,
D.SSN)
CROSS APPLY (SELECT TestDate,
Score
UNION ALL /*Unpivot the three test instances into a row each*/
SELECT TestDate2,
Score2
UNION ALL
SELECT TestDate3,
Score3) CA(TestDate, TestScore)
WHERE NOT ( CA.TestDate IS NULL
AND CA.TestScore IS NULL )
【讨论】:
这正是我想要的。我对其进行了修改以完美地工作。非常感谢您的帮助。以上是关于从单个非规范化表创建规范化表的主要内容,如果未能解决你的问题,请参考以下文章