Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Consulta de tabela cruzada com colunas dinâmicas no SQL Server 2008


A consulta que você precisará para obter os resultados em sua pergunta é:
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;

Resultado:
StudentID   Name    Computing   Maths   English
1           John    L2          E3      E2

Embora, como você possa descobrir, isso requer uma codificação rígida dos assuntos. Se sua lista de assuntos provavelmente mudar, essa consulta não será mais adequada.

Se você estiver confortável, poderá remediar isso com SQL dinâmico:
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
                    ,'[email protected]+'
            from StudentResults
            pivot (max(CourseLevel) for Course in ('[email protected]+')
                  ) p';

execute (@query);

Idealmente, porém, você simplesmente retornaria um conjunto de dados, como parece estar em sua tabela de origem e deixaria sua camada de relatório (SSRS, por exemplo) lidar com a dinâmica, para a qual é muito mais adequado do que o SQL puro.