如何在SQL Server中将多行转换为一行?

时间:2014-12-30 20:50:51

标签: sql sql-server join inner-join multirow

我的查询有问题。假设我有两个名为PersonInfoPersonEducation的表。我使用StudentId在这些表上应用了联接操作,我得到了类似的结果。

   StudentIdId      Name    University    Department     Status
   ---------------------------------------------------------------
      1             John    Cambridge     Computer       Graduated
      1             John    Berkeley      Mathematic     Graduated
      1             John    Boston        Economy        Ongoing

这只是学生(约翰)的一个例子。这表明约翰毕业于2所大学,仍在一所大学学习。大学数字可能会因学生而异。我的问题是如何在一行中显示这3行。我的意思是我想在一行中显示所有教育信息,以便不为一个人拥有多行。

提前感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

测试数据

DECLARE @TABLE TABLE (StudentIdId INT, Name VARCHAR(100), University VARCHAR(100)
                       , Department VARCHAR(100),[Status] VARCHAR(100))
INSERT INTO @TABLE VALUES 
(1 ,'John','Cambridge','Computer'  ,'Graduated'),
(1 ,'John','Berkeley' ,'Mathematic','Graduated'),
(1 ,'John','Boston'   ,'Economy'   ,'Ongoing'),
(2 ,'Pete','Cambridge','Computer'  ,'Graduated'),
(2 ,'Pete','Berkeley' ,'Mathematic','Graduated')

查询

SELECT t.StudentIdId
      ,t.Name
      ,STUFF((SELECT ', ' + University 
              FROM @TABLE 
              WHERE StudentIdId = t.StudentIdId
              FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)'),1,2,'') AS University
      ,STUFF((SELECT ', ' + Department 
              FROM @TABLE 
              WHERE StudentIdId = t.StudentIdId
              FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)'),1,2,'') AS Department
      ,STUFF((SELECT ', ' + [Status] 
              FROM @TABLE 
              WHERE StudentIdId = t.StudentIdId
              FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)'),1,2,'') AS [Status]

FROM @TABLE t 
GROUP BY t.StudentIdId ,t.Name

结果

╔═════════════╦══════╦═════════════════════════════╦═══════════════════════════════╦═══════════════════════════════╗
║ StudentIdId ║ Name ║         University          ║          Department           ║            Status             ║
╠═════════════╬══════╬═════════════════════════════╬═══════════════════════════════╬═══════════════════════════════╣
║           1 ║ John ║ Cambridge, Berkeley, Boston ║ Computer, Mathematic, Economy ║ Graduated, Graduated, Ongoing ║
║           2 ║ Pete ║ Cambridge, Berkeley         ║ Computer, Mathematic          ║ Graduated, Graduated          ║
╚═════════════╩══════╩═════════════════════════════╩═══════════════════════════════╩═══════════════════════════════╝

答案 1 :(得分:0)

这取决于您对输出的要求。

  1. 如果要在PersonEducation中聚合数据以计算状态,则可以加入PersonEducation表的子查询。有很多关于如何使用子查询以及如何按字段分组的文章。
  2. 类似的东西:

    SELECT pere.StudentId
        , pere.StudentName
        , peri.UniversityCount
        , peri.GraduatedStatusCout
        , peri.OngoingStatusCount
    FROM PersonInfo peri
    LEFT JOIN
        (SELECT StudentId
            , UniversityCount = COUNT(*)
            , GraduatedStatusCount = SUM(IIF(Status = 'Graduated', 1, 0))
            , OngoingStatusCount = SUM(IIF(Status = 'Ongoing', 1, 0))
        FROM PersonEducation
        GROUP BY StudentId) pere
        ON peri.StudentId = pere.StudentId;
    
    1. 如果你想让最后一所大学就读,那么你需要某种类型的参加日期的领域。有可能有多个大学同时有人参加,所以你需要有关如何挑选胜利者的规则。但是,在这些情况下,您可以使用ROW_NUMBER() in an OVER()子句来排序数据并过滤结果。

    2. 您可以按照here或其他任何文章中的说明将数据连接在一起。