SQL Server 2005 Pivot auf Unknown Anzahl der Spalten
-
03-07-2019 - |
Frage
ich mit einem Satz von Daten arbeite, die etwa wie folgt aussieht.
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
Der Name und die Anzahl der Zuordnungen dynamisch sind, muss ich Ergebnisse erhalten simlilar auf die folgenden.
Student | Assignment 1 | Assignment 2 | Assignment 3 | Total -------------------------------------------------------------------- Student A | 100 | 80 | null | 180 Student B | 100 | 80 | 100 | 280
Jetzt im Idealfall würde Ich mag die Säule auf eine „due date“ sortieren, die enthalten sein könnten / mit jedem Auftrag zugeordnet ist. Die Gesamt am Ende sein soll, wenn möglich (Es berechnet und aus der Abfrage, wenn möglich entfernt werden kann.)
Ich weiß, wie es für die 3 Aufgaben tun Dreh mit mit einfach den Spalten zu benennen, wird es versuchen, es in einer dynamischen Art und Weise zu tun, dass ich nicht eine gute Lösung für noch nicht gefunden haben. Ich versuche, diese auf SQL Server 2005
zu tunBearbeiten
Im Idealfall würde Ich mag dies implementieren, ohne dynamischen SQL zu verwenden, wie die gegen die Politik ist. Wenn es nicht möglich ist, ... dann wird ein funktionierendes Beispiel mit Dynamic SQL arbeiten.
Lösung
Ich weiß, dass Sie gesagt haben keinen dynamischen SQL
, aber ich sehe keine Möglichkeit, es in gerade SQL
zu tun.
Wenn Sie beachten Sie auch meine Antworten auf ähnliche Probleme bei Pivot-Tabellen und verketten Spalten und PIVOT in sQL 2005
Die dynamische SQL
ist es der Injektion nicht anfällig, und es gibt keinen Grund, es zu verbieten. Eine weitere Möglichkeit (wenn die Daten sehr selten verändern) ist Code-Generation zu tun - statt dynamischer SQL
wird die SQL
auf eine gespeicherte Prozedur in regelmäßigen Abständen erzeugt
Andere Tipps
Um diese Daten mit dynamischen SQL PIVOT
können Sie den folgenden Code in SQL Server 2005 +:
Tabelle erstellen:
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)
;
Dynamische 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)
Siehe SQL Fiddle mit Demo
Das Ergebnis ist:
| STUDENTNAME | ASSIGNMENT 1 | ASSIGNMENT 2 | ASSIGNMENT 3 | TOTAL |
--------------------------------------------------------------------
| StudentA | 100 | 80 | (null) | 180 |
| StudentB | 100 | 80 | 100 | 280 |
Die einzige Möglichkeit, die ich gefunden habe, dies zu tun ist dynamisch SQL zu verwenden und die Spaltenbeschriftungen in eine Variable setzen.
Sie könnten information_schema abfragen, um die Spaltennamen und -typen zu bekommen, dann das Ergebnis als Unterabfrage verwenden, wenn Sie Ihr Ergebnis Set bauen. Hinweis: Sie müssen wahrscheinlich die ein wenig Zugang Login ändern.
Dies ist die gleiche wie PIVOT in SQL 2005
Wenn diese Daten für den Verbrauch in einem Bericht können Sie eine SSRS Matrix verwenden. Es wird Spalten dynamisch aus Ergebnismenge erzeugen. Ich habe es oft verwendet -. Es ganz gut für dynamische Kreuztabellen Berichte funktioniert
Hier ist ein gutes Beispiel w / dynamisches SQL. 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