规范化具有不同结构的表

时间:2012-07-25 15:19:50

标签: sql sql-server database tsql database-normalization

我有一个规范化的表(表a)和一个非规范化的表(表b),如下所示:

enter image description here

我想在非规范化表中为每个父项的规范化表中插入一个新行。因此,如果表B中有一个记录,其中有两个父项用于studentID,我想在表A中插入两条记录,每个父表名与表B中的不同。

我一直在努力争取这个好几个小时,如果能做到这一点,任何帮助都会受到赞赏。

2 个答案:

答案 0 :(得分:0)

假设parentID是自动增量列,您可以这样做:

INSERT INTO NormalizedFamily(studentID, parentName)
SELECT studentID, parentName1
FROM FlatFamily
UNION
SELECT studentID, parentName2
FROM FlatFamily
WHERE parentName2 IS NOT NULL
UNION
SELECT studentID, parentName3
FROM FlatFamily
WHERE parentName3 IS NOT NULL
UNION
SELECT studentID, parentName4
FROM FlatFamily
WHERE parentName4 IS NOT NULL

在任何情况下,我都不明白为什么列parentId是规范化表的关键。事实上,同一个家长不能让多个学生与他相关?,关键词不应该是parentIDstudentID的组合吗?

答案 1 :(得分:0)

这是unpivot的意思。尽管如此,对于初学者来说,这是一种奇怪和难以理解的东西。这是一个完全hacky方式来做同样容易理解的事情:

 insert into NormalizedFamily (parentId, studentId, parentName)
 select p.parentName,
        p.parentId,
        f.studentId
   from Parent p
            inner join
        (select studentId, parentName1 as parentName from FlatFamily
         union all
         select studentId, parentName2 as parentName from FlatFamily
         union all
         select studentId, parentName3 as parentName from FlatFamily
         union all
         select studentId, parentName4 as parentName from FlatFamily
         union all
         select studentId, parentName5 as parentName from FlatFamily
        ) t                on t.parentName = p.parentName

以下是unpivot的工作原理。它基本上将列转换为行。所以试试这个select语句:

 SELECT studentId, parentColumnName, parentName
   FROM (SELECT studentId, parentName1, parentName2, parentName3, parentName4, parentName5
           FROM FlatFamily) f
UNPIVOT (parentName FOR parentColumnName IN (parentName1, parentName2, parentName3, parentName4, parentName5)) AS t