Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 动态SQL数据透视_Sql Server_Pivot - Fatal编程技术网

Sql server 动态SQL数据透视

Sql server 动态SQL数据透视,sql-server,pivot,Sql Server,Pivot,我正在使用以下SQL(与SQL Server 2016一起)来透视来自LMS(Moodle)的测试结果列表: 结果将是: 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

我正在使用以下SQL(与SQL Server 2016一起)来透视来自LMS(Moodle)的测试结果列表:

结果将是:

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吗

有什么更好的方法-对XML路径使用
Stuff()
,或者其他方法


我不能使用存储过程(应用程序不支持它们)。

不需要存储过程和用于逗号浓缩的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 ('+@COL_NAMES+'
    )
) PIVT
ORDER BY id_number'


EXEC (@SQL);

不需要存储过程,也不需要逗号连接的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 ('+@COL_NAMES+'
    )
) PIVT
ORDER BY id_number'


EXEC (@SQL);

这对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 

这对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 

请发布示例数据,从所有使用的表发布示例数据,从所有使用的表发布示例数据我在Management Studio中收到一个错误:Msg 102,级别15,状态1,第14行“;”附近的语法不正确我在ManagementStudio中遇到一个错误:msg102,级别15,状态1,第14行“;”附近的语法不正确