SSIS - 将多列拆分为单行

SSIS - Split multiple columns into single rows

下面是我需要分割的公寓的一个非常小的例子table。第一个 table 是具有 ID、名称和持续时间的课程 table。第二个table是一个学生table,只有学生姓名作为PK。第三个 table 将是课程 ID 和学生姓名的多对多。

Lesson Id Lesson Name Lesson Duration Student1 Student2 Student3 Student4
1 Maths 1 Hour Jean Paul Jane Doe
2 English 1 Hour Jean Jane Doe
  1. 我不知道如何使用 SSIS,使用学生 1、2、3 和 4 列将 Jean、Paul、Jane 和 Doe 分配给他们自己的 tables。当我弄清楚这一点时,我想我可以使用相同的逻辑将课程 ID 和列映射到第三个多对多 table?
  2. 我如何处理重复的条目,例如 Jean Jane 和 Doe 从第一行开始就已经存在,因此不需要将他们添加到 Students table。
  3. 我假设我使用条件拆分来跳过空值?例如,第二行的 Student4 为 Null。

感谢您的帮助。

如果是我,我会将其设计为 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 将处理数据的重复数据删除,我们将其包装在派生的 table 中以过滤 NULL。

我添加了一个明确的顺序,并不是因为它是必需的,但由于我假设您使用名称作为主键,所以我们在获取数据时避免排序操作。

将 OLE DB 源添加到您的数据流中,而不是在下拉列表中选择 table,您将使用上述查询。

向同一数据流添加一个 OLE DB 目标并将两者连接起来。假设你的目标 table 看起来像

CREATE TABLE dbo.Student
(
    StudentName varchar(50) NOT NULL CONSTRAINT PK__dbo__Student PRIMARY KEY(StudentName)
);

数据流 2 - 课程

这里是经销商的选择,您可以写查询或直接指向来源table。

使用 SSIS 的一个很好的做法是只将你需要的数据放入缓冲区,所以我会写一个像

这样的查询
SELECT DISTINCT S.[Lesson Id], S.[Lesson Name], S.[Lesson Duration]
FROM dbo.MyTable AS S;

我赞成在这里使用 distinct,因为我对你的数据了解不够,但如果扩展它并提供第二个数学 class 以容纳另外 4 名学生,它可能又是第 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 目标登陆您的桥table并完成它。

如果这是 homework/an 让您学习本机组件的作业...

请继续使用 3 数据流方法。一次尝试做太多事情会带来麻烦。

将宽数据移动到窄数据的操作是Unpivot操作。你会在 Student 和 bridge table 数据流中使用它,但老实说,我认为我在我的职业生涯中使用该组件的次数不到 10 次 and/or 在这里回答 SSIS 问题,我做了一个 很多

如果 Unpivot 操作生成 NULL,那么是的,您可能希望使用条件拆分来过滤掉这些行。

如果您的引用 table 更复杂,那么您可能会向桥 table 填充步骤添加一个 Lookup 组件以检索代理键。