Pregunta

Estoy trabajando con un conjunto de datos que se parecen a los siguientes.

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

El nombre y el número de asignaciones son dinámicos, necesito obtener resultados similares a los siguientes.

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

Lo ideal sería ordenar la columna según la fecha de vencimiento " que podría ser incluido / asociado con cada tarea. El total debe estar al final si es posible (se puede calcular y eliminar de la consulta si es posible).

Sé cómo hacerlo para las 3 asignaciones usando pivot con solo nombrar las columnas, está intentando hacerlo de una manera dinámica en la que aún no he encontrado una BUENA solución. Estoy tratando de hacer esto en SQL Server 2005

EDIT

Idealmente, me gustaría implementar esto SIN el uso de SQL dinámico, ya que está en contra de la política. Si no es posible ... entonces funcionará un ejemplo funcional con SQL dinámico.

¿Fue útil?

Solución

Sé que usted dijo que no hay SQL dinámico, pero no veo ninguna manera de hacerlo en SQL .

Si revisa mis respuestas a problemas similares en Tabla de pivote y Concatenar columnas y PIVOT en SQL 2005

El SQL dinámico no es vulnerable a la inyección, y no hay una buena razón para prohibirlo. Otra posibilidad (si los datos cambian con poca frecuencia) es hacer generación de código, en lugar de SQL dinámico, el SQL se genera en un procedimiento almacenado de forma regular.

Otros consejos

Para PIVOT esta información usando un sql dinámico puede usar el siguiente código en SQL Server 2005+:

Crear tabla:

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

PIVOTO dinámico:

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)

Vea Fiddle de SQL con demostración

El resultado es:

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

La única forma que he encontrado para hacer esto es usar SQL dinámico y colocar las etiquetas de columna en una variable.

puede consultar el esquema de información para obtener los nombres y tipos de columna, y luego usar el resultado como una subconsulta cuando construya su conjunto de resultados. Tenga en cuenta que es probable que deba cambiar un poco el acceso de inicio de sesión.

Esto es lo mismo que PIVOT en SQL 2005

Si estos datos son para consumo en un informe, podría utilizar una matriz SSRS. Generará columnas dinámicamente a partir del conjunto de resultados. Lo he usado muchas veces, funciona bastante bien para los informes dinámicos de tablas de referencias cruzadas.

Aquí hay un buen ejemplo con 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 bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top