简体   繁体   English

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

[英]Crosstab Query with Dynamic Columns in SQL Server 2008

I'm having trouble with a Cross Tab query in SQL Server and was hoping that someone could please help?我在 SQL Server 中遇到了交叉表查询的问题,希望有人能帮忙吗?

I have the following table:我有下表:

- Student ID - Name - Course     - Course Level -
- 1          - John - English    - E2 -
- 1          - John - Mathns     - E3 -
- 1          - John - Computing  - L2 -

Each learner has to sit an English, Maths and Computing Assessment and a level is given.每个学习者都必须参加英语、数学和计算机评估,并给出一个级别。

I need to report what one learner achieved in each assessment on one line like the following:我需要在一行中报告一名学习者在每次评估中取得的成绩,如下所示:

- StudentID - Name - English - Maths - Computing - 
- 1         - John - E2      - E3    - L2 -

I have been given this code from the comments below: Thank you @iamdave.我从下面的评论中得到了这个代码:谢谢@iamdave。

SELECT PERSON_CODE, [Computing], [Maths], [English]
FROM TT
PIVOT (MAX(LEVEL) FOR COURSE_CODE IN ([DL], [NUM15], [ENG15])) AS P

I just need to add a group by so that John only appears as one row as I am currently seeing this:我只需要添加一个组,以便约翰只显示为一行,因为我目前看到的是:

- StudentID - Name - English - Maths - Computing - 
- 1         - John - E2      - E3    - L2 -
- 1         - John - E2      - E3    - L2 -
- 1         - John - E2      - E3    - L2 -

Instead of:代替:

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

Thank you谢谢

The query you will need to get the results in your question is:获得问题结果所需的查询是:

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;

Output:输出:

StudentID   Name    Computing   Maths   English
1           John    L2          E3      E2

Though as you may be able to work out, this requires hard coding the subjects.尽管您可以解决,但这需要对主题进行硬编码。 If your list of subjects is likely to change, then this query will no longer be fit for purpose.如果您的主题列表可能会更改,则此查询将不再适用。

If you are comfortable, you can remedy this with dynamic SQL:如果你觉得舒服,你可以用动态 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);

Ideally though, you would simply return a set of data, as it appears to be in your source table and let your reporting layer (SSRS for example) handle the pivoting, which it is much better suited towards than pure SQL.理想情况下,您只需返回一组数据,因为它似乎在您的源表中,并让您的报告层(例如 SSRS)处理数据透视,这比纯 SQL 更适合。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM