SQL:将重复的实例合并为一行

时间:2016-05-10 08:59:29

标签: sql sql-server sql-server-2008 pivot aggregate-functions

我在我们的数据库上运行一个基本的SQL查询,它会带回学生数据。学生可以在不同的课程上有多个实例,例如:

StudentID        StudentFullName        Course        StartDate
123456           J.Bloggs               BA            01/11/2012
123456           J.Bloggs               MBA           01/07/2015
234567           R.Head                 BA            09/04/2014

我尝试做的是合并重复的学生记录(可能基于ID或名称)并将课程数据放入同一行,最终结果理想情况如下:

StudentID        StudentFullName        Course1       StartDate1       Course2    StartDate2
123456           J.Bloggs               BA            01/11/2012       MBA        01/07/2015
234567           R.Head                 BA            09/04/2014

可能会有学生有超过2门课程的情况,因此代码需要灵活允许(课程3,课程4等)。

我也会考虑运行查询,寻找那些开始将会是什么课程的学生#Course;'在一段时间后(> =' 2014/08 / 01')。

到目前为止,我只能通过运行原始代码然后在电子表格中进行编辑(耗时)手动重新创建所需的结果。

3 个答案:

答案 0 :(得分:1)

特别是因为您的课程数量很灵活,您将无法将其放入一个表格中。也就是说,SQL Server不支持"灵活的列表"作为一个概念。

相反,您的问题可能是normalization to the 2NF form之一。

考虑创建一个包含学生ID,课程,开始日期列的新表StudentCourses。 像J.Bloggs这样的学生将在那里有两个条目,而R.Head只有一个条目。 您当前的学生表仅保留学生信息,如姓名,出生日期,学分等。

然后,根据您的需要,您始终可以构建获取该信息的查询或视图。

答案 1 :(得分:0)

您是否在任何其他编程语言中使用SQL?如果是这样,您可以使用if-Statement添加新列,但动态添加或删除列会导致异常。 我认为创建一个单独的表可以获得最佳结果。那你应该有三个表:

学生数据(StudentID,StudentFullName)

课程(CourseID,CourseName)

学生课程(CourseID,StudentID,StartDate)

这是一个优化方案。

希望我能提供帮助,如果没有,请随时提出进一步的问题。

编辑:这可能需要更多的努力,因为课程是单独存储的,但它应该是最快,最节省存储的解决方案。 正如评论中所提到的:这是该计划的规范化。

可能更容易的是有两个表的方案: StudentData(StudentID,StudentFullName) 学生课程(CourseName,StudentID,StartDate)

答案 2 :(得分:0)

转动多列的最简单方法之一是使用聚合大小写表达式。

您必须使用ROW_NUMBER来确定课程是否为course1,course2等。然后只需在Case Case中使用生成的ROW_NUMBER。

SELECT  [StudentID],
        [StudentFullName],
        MAX(CASE WHEN Rn = 1 THEN [Course] END) AS Course1,
        MAX(CASE WHEN Rn = 1 THEN [StartDate] END) AS StartDate1,
        MAX(CASE WHEN Rn = 2 THEN [Course] END) AS Course2,
        MAX(CASE WHEN Rn = 2 THEN [StartDate] END) AS StartDate2
FROM    (
            SELECT  *, ROW_NUMBER() OVER (PARTITION BY [StudentID] ORDER BY [StartDate] DESC) Rn
            FROM    Table1
        ) t
GROUP BY [StudentID],
        [StudentFullName]

这些查询也可以通过构建MAX(CASE)部分动态完成。