2014-01-28 152 views
0

我正在嘗試使用數據透視表來動態創建列,但我沒有得到正在尋找的正確結果。我需要在每個問題(行)的自己的專欄中顯示所有可能的答案,並且在課程中有多個問題。如何將每個可能的答案生成爲一個列名稱,並按courseId和每行的questionId進行過濾?可能答案的數量因問題而異。這應該通過光標而不是透視來完成嗎?動態數據透視列與Sql Server中的相關表格

DECLARE @cols AS NVARCHAR(MAX), 
     @query AS NVARCHAR(MAX), 
     @courseID float(24) = 1 

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(questionID) 
      FROM answers 
      INNER JOIN questions ON questions.questionID = answers.questionID 
      WHERE questions.courseId = @courseID 
      order by 1 
         FOR XML PATH(''), TYPE 
        ).value('.', 'NVARCHAR(MAX)') 
         , 1, 1, ''); 

set @query = 'SELECT * from 
      (
       select Q.courseId, C.courseName, Q.question, Q.questionID, A.answer 
       from questions Q 
       inner join courses C ON Q.courseId = C.courseId 
       inner join answers A ON A.questionID = Q.questionID 
       where (Q.courseId = ''' + Str(@courseID) + ''') 
      ) x 
      pivot 
      (
       max(answer) 
       for questionId in (' + @cols + ') 
      ) AS p' 


execute(@query) 

當運行上面我得到:

[1],[10],[11],[12],[13],[14],[15],[16],[2],[3],[4],[5],[6],[7],[8],[9] 

由於生成列這是questionIds而不是「答案1,答案2 ...等」,並且它們並不顯示在訂購。

爲了簡潔這裏的目的是相關的列數據庫中的表:

課程

courseId 

問題

questionId question  courseId 

答案

AnswerId questionId answer 

任何幫助表示讚賞。

回答

1

你沒有提供你的表結構中的許多細節,但如果你想要的答案爲列,即Answer1Answer2等,那麼你需要創建一個使用row_number()針對每類似問題答案的數目列以下內容:

SET @cols = STUFF((SELECT ',' + QUOTENAME('Answer'+cast(seq as varchar(10))) 
      FROM 
      (
       select row_number() over(partition by q.questionid 
              order by a.answer) seq 
       from answers a 
       INNER JOIN questions q 
        ON q.questionID = a.questionID 
       WHERE q.courseId = @courseID 
      ) d 
      group by seq 
      order by seq 
        FOR XML PATH(''), TYPE 
       ).value('.', 'NVARCHAR(MAX)') 
        , 1, 1, ''); 

這將爲每個問題回答每一個序列,然後該序列號是用來創建新的列名。那麼你會改變你的PIVOT代碼:

set @query = 'SELECT * 
      from 
      (
       select Q.courseId, C.className, Q.question, Q.questionID, A.answer, 
        ''Answer''+cast(row_number() over(partition by q.questionid 
                 order by a.answer) as varchar(10)) seq 
       from questions Q 
       inner join classes C 
        ON Q.courseId = C.courseId 
       inner join answers A 
        ON A.questionID = Q.questionID 
       where (Q.courseId = ''' + Str(@courseID) + ''') 
      ) x 
      pivot 
      (
       max(answer) 
       for seq in (' + @cols + ') 
      ) AS p' 


execute(@query) 
+0

對不起,缺乏細節。我編輯我的問題,包括一些表結構。無論如何,你的例子完美無缺。謝謝! – Drew