下面是我需要拆分的平面表的一个非常小的例子。第一个表是"课程"表,其中包含ID、名称和持续时间。第二个表格是一个学生表格,只有学生姓名作为PK。第三个表格将是课程ID和学生姓名的多对多。
课程Id | 课程名称 | 课程持续时间学生1 | >学生2学生3>学生4 | ||
---|---|---|---|---|---|
1 | 数学 | <1小时>JeanPaulJane||||
2 | 英语 | <1小时>JeanJane
如果是我,我会将其设计为3个数据流。
数据流1-学生群体
由于我们假设学生的名字是独一无二的,所以我们需要建立一个独特名字的大列表。
SELECT D.*
FROM
(
SELECT S.Student1 AS StudentName
FROM dbo.MyTable AS S
UNION
SELECT S.Student2 AS StudentName
FROM dbo.MyTable AS S
UNION
SELECT S.Student3 AS StudentName
FROM dbo.MyTable AS S
UNION
SELECT S.Student4 AS StudentName
FROM dbo.MyTable AS S
)D
WHERE D.StudentName IS NOT NULL
ORDER BY D.StudentName;
在查询中使用UNION
将处理数据的重复数据消除,我们将其封装在派生表中以过滤NULL。
我添加了一个明确的顺序,并不是说它是必需的,但由于我假设您使用名称作为主键,所以当我们获得数据时,让我们避免排序操作。
将OLE DB源添加到数据流中,您将使用上面的查询,而不是在下拉列表中选择表。
将一个OLE DB目标添加到同一数据流,并将两者连接起来。假设你的目标表看起来像
CREATE TABLE dbo.Student
(
StudentName varchar(50) NOT NULL CONSTRAINT PK__dbo__Student PRIMARY KEY(StudentName)
);
数据流2-经验教训
经销商在这里选择,您可以编写查询,也可以直接指向源表。
使用SSIS的一个非常好的做法是只将所需的数据带入缓冲区,因此我会编写一个类似的查询
SELECT DISTINCT S.[Lesson Id], S.[Lesson Name], S.[Lesson Duration]
FROM dbo.MyTable AS S;
我喜欢这里的区别,因为我对你的数据了解不够,但如果它被扩展,并提供第二节数学课来容纳另外4名学生,它可能又是第Id课1。或者它可能是3,因为它表示课程时间或其他什么。
添加OLE DB目标并着陆数据。
数据流3-多对多
有几种不同的方法可以处理这个问题。我喜欢懒惰的方式,并重复我们从第一个数据流的方法
SELECT D.*
FROM
(
SELECT S.Student1 AS StudentName, S.[Lesson Id]
FROM dbo.MyTable AS S
UNION
SELECT S.Student2 AS StudentName, S.[Lesson Id]
FROM dbo.MyTable AS S
UNION
SELECT S.Student3 AS StudentName, S.[Lesson Id]
FROM dbo.MyTable AS S
UNION
SELECT S.Student4 AS StudentName, S.[Lesson Id]
FROM dbo.MyTable AS S
)D
WHERE D.StudentName IS NOT NULL
ORDER BY D.StudentName;
然后在你的桥接表中输入一个OLE DB目的地并完成它
如果这是让你学习本机组件的家庭作业/作业
请遵守3数据流方法。一次尝试做太多事情会带来麻烦。
将宽数据移动到窄数据的操作是取消预览操作。你会在学生和桥接表数据流中使用它,但老实说,我想我在职业生涯中和/或在这里回答SSIS问题时使用该组件的次数不到10次,我做了很多。
如果Unpivot操作生成NULL,那么是的,您可能希望使用条件拆分来筛选出这些行。
如果引用表更复杂,那么您可能会在桥表填充步骤中添加一个Lookup组件来检索代理项。