从单个非规范化表创建规范化表

时间:2015-07-15 19:06:34

标签: sql-server join

好吧,在我试图尽可能清楚地解释这一点时请耐心等待。

我有一个来自当前在SQL中的dBASE的遗留数据表,我需要将其分解为规范化表。旧表包含LastName,FirstName,SSN,TestDate,Score,TestDate2,Score2,TestDate3,Score3的列。当旧系统正在使用,并且操作员需要添加额外的测试时,他们必须使用相同的LastName,FirstName,SSN创建一个全新的记录以进入第四个测试,因为每个记录只有三个考试的位置。新数据库具有LastName,FirstName和SSN的employee表,以及每个检查的Test表。我无法弄清楚如何编写程序以获得员工的唯一实例,以及所有测试记录,当它有多个与之关联的行时。

这是一个"示例"数据...... enter image description here

正确方向的一点将是一个巨大的帮助!谢谢!!

编辑:SQL Server 2012,员工表目前有一个EmployeeId,它将用作IDENTITY字段。 Exam表将EmployeeId作为FK。

1 个答案:

答案 0 :(得分:4)

您可以使用以下内容

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 )