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

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 ) 

【讨论】:

这正是我想要的。我对其进行了修改以完美地工作。非常感谢您的帮助。

以上是关于从单个非规范化表创建规范化表的主要内容,如果未能解决你的问题,请参考以下文章

将非规范化表转换为嵌套结构

MySQL INSERT ... 从 1 个表中选择 2 个表

在这种情况下,非规范化表是否可以接受?

如何在 GCP 上执行数据非规范化?

雪花数据加载最佳实践规范化还是非规范化?

将非规范化文件中的数据加载到规范化表中