【问题标题】:Crosstab Query with Dynamic Columns in SQL Server 2008SQL Server 2008 中带有动态列的交叉表查询
【发布时间】:2017-06-15 14:41:11
【问题描述】:

我在使用 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 -

我从下面的 cmets 获得了这个代码:谢谢@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 -

谢谢

【问题讨论】:

  • 您的表列与查询不一致。先改正
  • 对不起,我应该解释一下 StudentID 和 Person_Code 是相同的字段。谢谢,

标签: sql sql-server sql-server-2008 pivot pivot-table


【解决方案1】:

您需要在问题中获得结果的查询是:

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);

不过,理想情况下,您只需返回一组数据,因为它似乎在您的源表中,并让您的报告层(例如 SSRS)处理数据透视,这比纯 SQL 更适合。

【讨论】:

  • 感谢您回到我身边。它已经对课程进行了调整,但我仍然有每个学习者的重复行列表,而不是 John 只显示一次。
  • @MikeWatkins 根据您的测试数据,这些查询有效。您不能提供不具代表性的数据集并期望此处提供的解决方案在其他地方也能发挥作用。请更新您的问题以显示您正在使用的数据的代表性样本。
  • 抱歉,我是该网站的新手。为了进一步解释,我有一个表格,其中可以根据学生完成测试的次数复制 StudentID。您已经为我解决了旋转课程的问题,但这是我仍然看到的而不是一行:PERSON_CODE DL NUM15 ENG15 39310 NULL e2 NULL 39310 NULL NULL e3 39310 e2 NULL NULL
  • @MikeWatkins 请使用这些详细信息以及支持数据更新您的问题。如果您可以包含任何其他区分返回结果的列,例如测试日期,这也会有所帮助。使用这些新字段,您还需要更新所需的输出。
【解决方案2】:
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

【讨论】:

    猜你喜欢
    • 2012-09-07
    • 2014-04-01
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-17
    相关资源
    最近更新 更多