Question

Je travaille avec un ensemble de données qui ressemble à ce qui suit.

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

Le nom et le nombre d’affectations étant dynamiques, je dois obtenir des résultats identiques à ceux-ci.

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

Idéalement, j'aimerais trier la colonne en fonction d'une "date d'échéance". qui pourrait être inclus / associé à chaque mission. Le total doit être à la fin si possible (il peut être calculé et supprimé de la requête si possible).

Je sais comment le faire pour les 3 assignations utilisant pivot en nommant simplement les colonnes, c’est essayer de le faire de façon dynamique pour laquelle je n’ai pas encore trouvé de bonne solution. J'essaie de faire cela sur SQL Server 2005

MODIFIER

Idéalement, j'aimerais implémenter ceci SANS utiliser SQL dynamique, car cela est contraire à la politique. Si ce n’est pas possible, un exemple de travail avec Dynamic SQL fonctionnera.

Était-ce utile?

La solution

Je sais que vous avez dit qu'il n'y avait pas de SQL dynamique, mais je ne vois aucun moyen de le faire en mode SQL .

Si vous consultez mes réponses à des problèmes similaires à l'adresse table pivot et Concaténer des colonnes et PIVOT dans SQL 2005

Le code SQL dynamique n’est pas vulnérable à l’injection et il n’ya aucune raison de l’interdire. Une autre possibilité (si les données changent très peu fréquemment) est de générer du code - au lieu de SQL dynamique, le SQL est généré régulièrement dans une procédure stockée.

Autres conseils

Pour PIVOT ces données à l'aide de SQL dynamique, vous pouvez utiliser le code suivant dans SQL Server 2005 +:

Créer un tableau:

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

PIVOT dynamique:

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)

Voir Fiddle SQL avec une démonstration

Le résultat est:

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

Le seul moyen que j'ai trouvé de faire cela est d'utiliser du SQL dynamique et de mettre les étiquettes de colonne dans une variable.

vous pouvez interroger information_schema pour obtenir les noms et les types de colonnes, puis utiliser le résultat en tant que sous-requête lorsque vous créez votre jeu de résultats. Notez que vous devrez probablement modifier un peu l'accès à la connexion.

C’est la même chose que PIVOT dans SQL 2005

Si ces données sont destinées à la consommation dans un rapport, vous pouvez utiliser une matrice SSRS. Il générera des colonnes de manière dynamique à partir de l'ensemble de résultats. Je l'ai utilisé à plusieurs reprises - cela fonctionne assez bien pour les rapports d'analyse croisée dynamiques.

Voici un bon exemple avec SQL dynamique. 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top