2017-08-18 35 views
1

私たちのLMS(ムードル)から試験結果の一覧を旋回するように(SQL Serverの2016年と)次のSQLを使用しています:動的SQLピボット

SELECT * 
FROM 
    (SELECT 
     u.firstname AS name, 
     u.lastname AS last_name, 
     u.idnumber AS id_number, 
     gi.itemname AS exam_name, 
     CAST(gg.finalgrade/gi.grademax * 100 AS integer) AS grade 
    FROM 
     mdl_grade_grades gg 
    INNER JOIN 
     mdl_grade_items gi ON gg.itemid = gi.id 
    INNER JOIN 
     mdl_course c ON gi.courseid = c.id 
    INNER JOIN 
     mdl_user u ON gg.userid = u.id 
    WHERE 
     (gi.itemname IS NOT NULL) 
     AND (gi.courseid = 123)) SOURCE 
PIVOT 
    (MAX(grade) 
    FOR exam_name IN ([Exam ABC], [Exam DEF], [Exam GHI], 
         [Exam JKL], [Exam XYZ]) 
    ) PIVT 
ORDER BY 
    id_number 

結果は次のようになります。

name last name id number division region  branch  Exam ABC Exam DEF Exam GHI Exam JKL Exam XYZ 
John Tester  3343664  ABC   WEST RGN A AGY  65         44 
Kenny Quipton  4342423  DDA   CENTRAL  RGN FRN  88   66   90      89 
Molefi Manase  5456545  CCS   ABC RGN  XXX SOL  74   90   85   80   77 

私の唯一の問題は、FOR IN(...)のリストにテスト名をハードコードする必要があるため、何か変更するたびにリストを手動で更新する必要があることです。

動的SQLを使用してこのSQLを書き換えることはできますか?

何が良いですか - Stuff()またはFOR XML PATHなどを使用していますか?

ストアドプロシージャを使用することはできません(アプリケーションではサポートされていません)。

+0

ポストサンプルデータ、すべてのテーブルから、私はManagement Studioでのエラーを取得してい – Matt

答えて

0

カンマ連結のストアドプロシージャとFOR XMLパスは不要です。 以下のコードをクエリビルダに入れ、データベースサーバーに送信してください。

DECLARE @SQL VARCHAR(MAX)='', @COL_NAMES VARCHAR(MAX)=''; 


--PREPARING EXAM NAMES LIST 
SELECT @COL_NAMES = @COL_NAMES+ itemname+',' FROM (
SELECT DISTINCT gi.itemname 
FROM mdl_grade_grades gg 
INNER JOIN mdl_grade_items gi ON gg.itemid = gi.id 
INNER JOIN mdl_course c ON gi.courseid = c.id 
INNER JOIN mdl_course_categories cc ON c.category = cc.id 
INNER JOIN mdl_user u ON gg.userid = u.id 
WHERE (gi.itemname IS NOT NULL) 
AND (gi.courseid = 123) 
); 

SELECT @COL_NAMES = LEFT(@COL_NAMES,LEN(@COL_NAMES)-1); 



--PREPARING DYNAMIC QUERY 
SELECT @SQL = 
'SELECT * FROM (
    SELECT 
     u.firstname AS name, 
     u.lastname AS last_name, 
     u.idnumber AS id_number, 
     gi.itemname AS exam_name, 
     CAST(gg.finalgrade/gi.grademax * 100 AS integer) AS grade 
    FROM mdl_grade_grades gg 
    INNER JOIN mdl_grade_items gi ON gg.itemid = gi.id 
    INNER JOIN mdl_course c ON gi.courseid = c.id 
    INNER JOIN mdl_course_categories cc ON c.category = cc.id 
    INNER JOIN mdl_user u ON gg.userid = u.id 
    WHERE (gi.itemname IS NOT NULL) 
    AND (gi.courseid = 123) 
) SOURCE 
PIVOT (
    MAX(grade) 
    FOR exam_name IN ('[email protected]_NAMES+' 
    ) 
) PIVT 
ORDER BY id_number' 


EXEC (@SQL); 
+0

使用してください: メッセージ102、レベル15 、状態1、行14 ';'の近くの構文が正しくありません。 – luisdev

0

これはfor xml使用していますが、同じいずれかを動作するはず方法

DECLARE @exams nvarchar(max), @sql nvarchar(max) 
SET  @exams = SELECT STUFF(SELECT ',', + QUOTENAME(t.itemname) 
         FROM (
          SELECT DISTINCT gi.itemname 
          FROM mdl_grade_items gi 
          WHERE gi.itemname IS NOT NULL AND gi.courseid = 123 
          ORDER BY gi.itemname 
         ) t 
       FOR XML PATH(''), 0, 1, '') 

SET @sql = N' 
    SELECT * 
    FROM 
     (SELECT 
      u.firstname AS name, 
      u.lastname AS last_name, 
      u.idnumber AS id_number, 
      gi.itemname AS exam_name, 
      CAST(gg.finalgrade/gi.grademax * 100 AS integer) AS grade 
     FROM 
      mdl_grade_grades gg 
     INNER JOIN 
      mdl_grade_items gi ON gg.itemid = gi.id 
     INNER JOIN 
      mdl_course c ON gi.courseid = c.id 
     INNER JOIN 
      mdl_user u ON gg.userid = u.id 
     WHERE 
      (gi.itemname IS NOT NULL) 
      AND (gi.courseid = 123)) SOURCE 
    PIVOT 
     (MAX(grade) 
     FOR exam_name IN (' + @exams + ') 
     ) PIVT 
    ORDER BY 
     id_number 
' 

EXEC sp_executesql @sql 
関連する問題