2017-10-09 168 views
1

如果能夠幫助我解決以下問題,我將不勝感激。 這是一個非標準化,簡化了我的數據集模型。它顯示學生會議。每個學生每次可能有0,1或2個同學。 我想從這裏去:SQL Server數據透視表。動態創建分組

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 

..to這裏:

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')。 我可以在不添加額外列的情況下實現相同的結果,或者至少在運行時創建額外的列嗎?

謝謝。

Chris。

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 

回答

0

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

+0

非常感謝Giorgos。這是一個很好的方法!我注意到的唯一想法是,即使在記錄中沒有同學時,以下行返回1而不是0: COUNT(*)AS NumOfCoStudnts 當我將其更改爲 時,我得到正確的結果COUNT(CoStudent)AS NumOfCoStudnts –

+0

@ChrisKotsiopoulos是的,這是一個很好的發現。 'COUNT(*)'統計屬於該組的記錄數,COUNT(CoStudent)'忽略空值,並且正確地記錄聯合學生的數量。 –