SQL Server 2008中具有动态列的交叉表查询

SQL Server 2008中具有动态列的交叉表查询,sql,sql-server,sql-server-2008,pivot,pivot-table,Sql,Sql Server,Sql Server 2008,Pivot,Pivot Table,我在SQL Server中遇到交叉表查询问题,希望有人能帮我 我有下表: - Student ID - Name - Course - Course Level - - 1 - John - English - E2 - - 1 - John - Mathns - E3 - - 1 - John - Computing - L2 - 每个学员都必须参加英语、数学和计算机评估,并给出一个等级 我需要在一行上报告一名学员

我在SQL Server中遇到交叉表查询问题,希望有人能帮我

我有下表:

- Student ID - Name - Course     - Course Level -
- 1          - John - English    - E2 -
- 1          - John - Mathns     - E3 -
- 1          - John - Computing  - L2 -
每个学员都必须参加英语、数学和计算机评估,并给出一个等级

我需要在一行上报告一名学员在每次评估中取得的成绩,如下所示:

- StudentID - Name - English - Maths - Computing - 
- 1         - John - E2      - E3    - L2 -
下面的评论给了我这个代码:谢谢@iamdave

SELECT PERSON_CODE, [Computing], [Maths], [English]
FROM TT
PIVOT (MAX(LEVEL) FOR COURSE_CODE IN ([DL], [NUM15], [ENG15])) AS P
我只需要添加一个group by,以便John只显示为一行,因为我当前看到了以下内容:

- StudentID - Name - English - Maths - Computing - 
- 1         - John - E2      - E3    - L2 -
- 1         - John - E2      - E3    - L2 -
- 1         - John - E2      - E3    - L2 -
而不是:

- StudentID - Name - English - Maths - Computing - 
- 1         - John - E2      - E3    - L2 -
- 2         - Amy  - L1      - L2    - E3 -

谢谢

您需要查询以下问题的结果:

SELECT studentId,
StudentName,
English,
Maths,
Computing
FROM (
SELECT T.StudentId,
    T.StudentName,
    T.Course,
    T.CourseLevel
FROM Test T
) AS J
PIVOT(MAX(CourseLevel) FOR Course IN (
        [English],
        [Maths],
        [Computing]
        )) AS P
create table StudentResults(StudentID int,Name nvarchar(50),Course nvarchar(50), CourseLevel nvarchar(10));
insert into StudentResults values(1,'John','English','E2'),(1,'John','Maths','E3'),(1,'John','Computing','L2');

select StudentID
        ,Name
        ,[Computing]
        ,[Maths]
        ,[English]
from StudentResults
pivot(max(CourseLevel) for Course in([Computing],[Maths],[English])
     ) as p;
输出:

StudentID   Name    Computing   Maths   English
1           John    L2          E3      E2
尽管你可能会解决这个问题,但这需要对主题进行硬编码。如果您的主题列表可能会更改,则此查询将不再适用

如果您觉得舒服,可以使用动态SQL解决这一问题:

declare @cols as  nvarchar(max)
       ,@query as nvarchar(max);

set @cols = stuff(
                   (select distinct ','+quotename(Course)
                    from StudentResults
                    for xml path(''),type).value('.','nvarchar(max)'
                   )
                 ,1,1,''
                 );

set @query = 'select StudentID
                    ,Name
                    ,'+@cols+'
            from StudentResults
            pivot (max(CourseLevel) for Course in ('+@cols+')
                  ) p';

execute (@query);

理想情况下,您只需返回一组数据,就像它出现在源表中一样,并让您的报告层(例如SSR)处理数据透视,这比纯SQL更适合。

您的表列与查询不一致。首先更正抱歉,我应该解释StudentID和Person_代码是相同的字段。谢谢,谢谢你回来找我。它已经成功地调整了课程,但我仍然为每个学员列出了一个重复的行列表,而不是John只显示一次。@MikeWatkins根据您的测试数据,这些查询是有效的。您不能提供一个非代表性的数据集,而期望这里提供的解决方案在其他地方起作用。请更新您的问题,以显示您正在处理的数据的代表性样本。很抱歉,我对该网站不熟悉。为了进一步解释,我有一个表,根据学生完成测试的次数,可以复制StudentID。您已经为我解决了旋转课程的问题,但这是我仍然看到的,而不是一行:人员代码DL NUM15 ENG15 39310 NULL e2 NULL 39310 NULL e3 39310 e2 NULLNULL@MikeWatkins请更新您的询问这些细节以及支持数据。如果您可以包含区分返回结果的任何其他列,例如测试日期,这也会有所帮助。使用这些新字段,您还需要更新所需的输出。