Pergunta

Eu estou trabalhando com um conjunto de dados que é algo como o seguinte.

StudentName  | AssignmentName |  Grade
---------------------------------------
StudentA     | Assignment 1   | 100
StudentA     | Assignment 2   | 80
StudentA     | Total          | 180
StudentB     | Assignment 1   | 100
StudentB     | Assignment 2   | 80
StudentB     | Assignment 3   | 100
StudentB     | Total          | 280

O nome e número de atribuições são dinâmica, eu preciso para obter resultados simlilar para o seguinte.

Student      | Assignment 1  | Assignment 2  | Assignment 3  | Total
--------------------------------------------------------------------
Student A    | 100           | 80            | null          | 180
Student B    | 100           | 80            | 100           | 280

Agora, idealmente, gostaria de classificar a coluna baseada em uma "data de vencimento", que poderia ser incluída / associado a cada tarefa. O total deve estar no final, se possível (Pode ser calculado e removido a partir da consulta, se possível.)

Eu sei como fazê-lo para os 3 trabalhos usando pivô com simplesmente nomear as colunas, que está a tentar fazê-lo de uma forma dinâmica que eu não tenha encontrado uma solução boa para ainda. Eu estou tentando fazer isso em SQL Server 2005

Editar

Idealmente, eu gostaria de implementar isso sem usar SQL dinâmico, como que é contra a política. Se não é possível ... então um exemplo de trabalho com Dynamic SQL vai funcionar.

Foi útil?

Solução

Eu sei que você disse que não SQL dinâmico, mas eu não vejo nenhuma maneira de fazê-lo em SQL reta.

Se você verificar as minhas respostas para problemas semelhantes em e Colunas concatenar e PIVOT no SQL 2005

O SQL dinâmica não é vulnerável a injeção, e não há nenhuma boa razão para proibi-la. Outra possibilidade (se os dados está mudando muito raramente) é fazer de geração de código -. Em vez de SQL dinâmico, o SQL é gerado para um procedimento armazenado em uma base regular

Outras dicas

Para PIVOT esses dados usando SQL dinâmico, você pode usar o seguinte código no SQL Server 2005 +:

Criar tabela:

CREATE TABLE yourtable
    ([StudentName] varchar(8), [AssignmentName] varchar(12), [Grade] int)
;

INSERT INTO yourtable
    ([StudentName], [AssignmentName], [Grade])
VALUES
    ('StudentA', 'Assignment 1', 100),
    ('StudentA', 'Assignment 2', 80),
    ('StudentA', 'Total', 180),
    ('StudentB', 'Assignment 1', 100),
    ('StudentB', 'Assignment 2', 80),
    ('StudentB', 'Assignment 3', 100),
    ('StudentB', 'Total', 280)
;

Dinâmica PIVOT:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(AssignmentName) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT StudentName, ' + @cols + ' from 
             (
                select StudentName, AssignmentName, grade
                from yourtable
            ) x
            pivot 
            (
                min(grade)
                for assignmentname in (' + @cols + ')
            ) p '

execute(@query)

SQL Fiddle com demonstração

O resultado é:

| STUDENTNAME | ASSIGNMENT 1 | ASSIGNMENT 2 | ASSIGNMENT 3 | TOTAL |
--------------------------------------------------------------------
|    StudentA |          100 |           80 |       (null) |   180 |
|    StudentB |          100 |           80 |          100 |   280 |

A única maneira que eu encontrei para fazer isso é usar SQL dinâmico e colocar os rótulos de coluna em uma variável.

Você pode consultar information_schema para obter os nomes de colunas e tipos, em seguida, usar o resultado como uma subconsulta quando você construir seu conjunto de resultados. Note que você provavelmente terá de alterar o acesso do logon um pouco.

Este é o mesmo que no SQL 2005

Se esses dados é para o consumo em um relatório, você poderia usar uma matriz SSRS. Ele irá gerar colunas dinamicamente a partir de conjunto de resultados. Eu usei-o muitas vezes -. Ele funciona muito bem para relatórios de referência cruzada dinâmica

Aqui está um bom exemplo w / SQL dinâmico. http: //www.simple- talk.com/community/blogs/andras/archive/2007/09/14/37265.aspx

SELECT TrnType
INTO #Temp1
FROM
(
    SELECT '[' + CAST(TransactionType AS VARCHAR(4)) + ']' AS TrnType FROM tblPaymentTransactionTypes
) AS tbl1

SELECT * FROM #Temp1

SELECT * FROM
(
    SELECT FirstName + ' ' + LastName AS Patient, TransactionType, ISNULL(PostedAmount, 0) AS PostedAmount
    FROM tblPaymentTransactions
            INNER JOIN emr_PatientDetails ON tblPaymentTransactions.PracticeID = emr_PatientDetails.PracticeId
            INNER JOIN tblPaymentTransactionDetails ON emr_PatientDetails.PatientId = tblPaymentTransactionDetails.PatientID
                        AND tblPaymentTransactions.TransactionID = tblPaymentTransactionDetails.TransactionID
    WHERE emr_PatientDetails.PracticeID = 152
) tbl
PIVOT (SUM(PostedAmount) FOR [TransactionType] IN (SELECT * FROM #Temp1)
) AS tbl4
select studentname,[Assign1],[Assign2],[Assign3],[Total] 
from 
(
 select studentname, assignname, grade from student
)s
pivot(sum(Grade) for assignname IN([Assign1],[Assign2],[Assign3],[Total])) as pvt
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top