【问题标题】:SQL Server pivot. Create grouping dynamicallySQL Server 数据透视。动态创建分组
【发布时间】:2017-10-09 15:05:46
【问题描述】:

如果您能帮助我解决以下问题,我将不胜感激。 这是我的数据集的非规范化简化模型。它显示学生会话。每个学生每节课可能有 0、1 或 2 名合作学生。 我想从这里出发:

SessionID   StudentID   Name    LastName    CoStudent
------------------------------------------------------------------
123         112         John    Smith       Mary Henderson
123         112         John    Smith       Chris Jameson
456         571         Panos   Kotsos      NULL
510         95          Adam    Jones       Ed Stevenson
850         56          Ed      Stevenson   Adam Jones
160         401         Mary    Henderson   John Smith
160         401         Mary    Henderson   Lucy Smith

..到这里:

SessionID   StudentID   Name    LastName    CoStudent1      CoStudent2      NumOfCoStudnts
---------------------------------------------------------------------------------------
123         112         John    Smith       Mary Henderson  Chris Jameson   2
160         401         Mary    Henderson   John Smith      Lucy Smith      2
456         571         Panos   Kotsos      NULL            NULL            0
510         95          Adam    Jones       Ed Stevenson    NULL            1
850         56          Ed      Stevenson   Adam Jones      NULL            1

我认为这可以使用 PIVOT 查询来完成。问题是我实现它的唯一方法是硬编码一个额外的列:CoStud1_2(值'CoStudent1','CoStudent2')。 我是否可以在不添加额外列的情况下或至少通过在运行时创建额外列来获得相同的结果?

谢谢。

克里斯。

DECLARE @STUDENTS TABLE 
  ( 
     sessionid          INT, 
     studentid          INT, 
     NAME               VARCHAR(100), 
     lastname           VARCHAR(100), 
     costud1_2          VARCHAR(100), 
     numberofcostudents VARCHAR(100) 
  ) 
INSERT INTO @STUDENTS 
VALUES
    (123,112,'John','Smith','Mary Henderson', 'CoStudent1'),
    (123,112,'John','Smith','Chris Jameson', 'CoStudent2'),
    (456,571,'Panos','Kotsos',NULL, NULL),
    (510,95,'Adam','Jones','Ed Stevenson', 'CoStudent1'),
    (850,56,'Ed','Stevenson','Adam Jones', 'CoStudent1'),
    (160,401,'Mary','Henderson','John Smith', 'CoStudent1'),
    (160,401,'Mary','Henderson','Lucy Smith', 'CoStudent2')

SELECT *, 
       Count(costudent1) + Count(costudent2) AS NumberOfCoStudents 
FROM   (-- Query goes here 
       SELECT * 
        FROM   @STUDENTS) t 
       PIVOT (Max(costud1_2) 
             FOR numberofcostudents IN ([CoStudent1],[CoStudent2]) )p 
GROUP  BY p.sessionid, 
          p.studentid, 
          p.NAME, 
          p.lastname, 
          p.costudent1, 
          p.costudent2

【问题讨论】:

    标签: sql-server pivot


    【解决方案1】:

    Ypu 可以使用ROW_NUMBER 来创建这个额外的列,用于区分同学 1 和 2。然后使用 条件聚合 来获得所需的结果:

    ;WITH CTE AS (
       SELECT sessionid, studentid, name, lastname, CoStudent,
              ROW_NUMBER() OVER (PARTITION BY sessionid, studentid, name, lastname
                                 ORDER BY CoStudent) AS rn
       FROM @STUDENTS
    ) 
    SELECT sessionid, studentid, name, lastname, 
           MAX(CASE WHEN rn = 1 THEN CoStudent END) AS CoStudent1,
           MAX(CASE WHEN rn = 2 THEN CoStudent END) AS CoStudent2,
           COUNT(CoStudent) AS NumOfCoStudnts
    FROM CTE
    GROUP BY sessionid, studentid, name, lastname
    

    注意:对于动态数量的同学,1、2、...、n,你必须使用动态sql。

    Demo here

    【讨论】:

    • 非常感谢乔治。这是一个很好的方法!我注意到的唯一想法是,即使记录中没有合作学生,以下行也会返回 1 而不是 0: COUNT(*) AS NumOfCoStudnts 当我将其更改为时得到正确的结果: COUNT(CoStudent) AS NumOfCoStudnts
    • @ChrisKotsiopoulos 是的,这是一个很好的收获。 COUNT(*) 计算属于该组的记录数,其中COUNT(CoStudent) 忽略空值,并正确计算共同学生的数量。
    猜你喜欢
    • 2015-06-06
    • 2014-10-16
    • 2014-07-26
    • 1970-01-01
    • 2013-02-09
    • 2018-11-22
    • 1970-01-01
    • 2012-06-10
    • 2015-06-08
    相关资源
    最近更新 更多