Ressourcen zu Pivot-Tabellen in SQL Server

Seit Jahrzehnten stehe ich irgendwie auf Kriegsfuß mit SQL. So eine Art Hassliebe. Ich brauche SQL sehr häufig und finde die Syntax trotzdem furchtbar.

JOINs habe ich inzwischen relativ gut verstanden, glaube ich, um die PIVOT-Funktionalität habe ich bisher einen Bogen gemacht.

Doch aktuell war das nicht mehr möglich. Deswegen habe ich mir zahlreiche Ressourcen angeschaut.

Ressourcen/Tutorials

Das oberste Tutorial war für mich das Verständlichste.

Im Grunde ist PIVOT einfach ein 90-Grad-Rotieren von Zeilen in Spalten.

Eigenes Beispielprojekt

Ich habe mir eine neue SQL-Server-Datenbank mit genau zwei Tabellen erstellt, die mein „echtes“ Problem so weit vereinfachen, dass ich damit die Lösung isoliert angehen und lösen kann.

Also quasi das klassische „Minimal, Reproducible Example“.

Struktur

Es gibt eine Kopfdatensatz-Tabelle MyForm:

CREATE TABLE [MyForm](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[Name] [nvarchar](250) NOT NULL,
	[DateCreated] [datetime] NOT NULL)

Und es gibt eine Detaildatensatz-Tabelle MyFormField mit Name-Werte-Paaren:

CREATE TABLE [MyFormField](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[MyFormId] [int] NOT NULL,
	[FieldName] [nvarchar](250) NOT NULL,
	[FieldValue] [nvarchar](max) NULL)

sowie dem Fremdschlüssel:

ALTER TABLE [MyFormField] 
WITH CHECK ADD CONSTRAINT [FK_MyFormField_MyForm] 
FOREIGN KEY([MyFormId])
REFERENCES [MyForm] ([Id])

Grafisch schaut das so aus:

Daten

Die Tabelle MyForm ist so gefüllt:

image

Und die Tabelle MyFormField ist so gefüllt:

Pivot-Abfrage

SELECT 
	-- Die Kopfdatensatz-Spalten holen.
	FormId, FormName, 

	-- Die Detaildatensatz-Spalten als Pivots holen.
	[Field A], [Field B], [Field C], [Field D]

FROM
(
	-- Hier die Kopfdaten und die Detaildatensätze redundant 
	-- zusammen joinen, damit wir aus das gesamte pivoten können.
	SELECT        
		MyForm.Id AS FormId, 
		MyForm.Name AS FormName, 
		MyFormField.FieldName, 
		MyFormField.FieldValue
	FROM            
		MyForm LEFT OUTER JOIN
        MyFormField ON MyForm.Id = MyFormField.MyFormId
) t
PIVOT
(
	-- Irgendwas aus der Detailtabelle als Aggregatsfunktion.
	MAX(FieldValue) 

	-- Die Zeilen als Spalten transponieren.
	FOR FieldName IN ([Field A], [Field B], [Field C], [Field D])
) as pvt

Ergebnis

Die obige Abfrage hat dann dieses Ergebnis geliefert:

image

Das kann ich dann entsprechend adaptieren auf mein „echtes“ Projekt.