Komplexe Pivot-Tabelle

13/05/2008 - 14:27 von Thomas Schremser | Report spam
Hallo allerseits!

Ich habe folgende Tabelle:

CREATE TABLE Berechtigung
(
ID int NOT NULL PRIMARY KEY,
PersonID int NOT NULL,
BCode char(1) NOT NULL,
Ort varchar(100) NOT NULL,
Von datetime NOT NULL
)

Diese enthàlt Daten, die in etwa so aussehen:

ID PersonID BCode Ort Von
1 10 P Wien 24.01.1970
2 10 P Salzburg 07.05.1972
3 11 A Berlin 17.03.1985
4 11 N Wien 20.03.1985
5 12 A Hamburg 25.11.1992
6 10 D Wien 01.08.2007

Aus diesen Daten wird eine Pivot-Tabelle gebildet, die pro PersonID und Bdld
das höchste Datum je BCode für die Codes P, N, und A enthàlt:

SELECT PersonID,
MAX(CASE WHEN BCode = 'P' THEN Von ELSE NULL END) AS PVon,
MAX(CASE WHEN BCode = 'N' THEN Von ELSE NULL END) AS NVon,
MAX(CASE WHEN BCode = 'A' THEN Von ELSE NULL END) AS AVon
FROM Berechtigung
WHERE BCode IN('P', 'N', 'A')

Dies ergibt

PersonID PVon NVon AVon
10 07.05.1972 NULL NULL
11 NULL 20.03.1985 17.03.1985
12 NULL NULL 25.11.1992

Soweit ist's ja noch kein Problem. Nun soll aber der jeweilige Ort
auch mit in die Pivot-Tabelle mit aufgenommen werden, also als Ergebnis
das Folgende herauskommen:

PersonID PVon POrt NVon NOrt AVon AOrt
10 07.05.1972 Salzburg NULL NULL NULL NULL
11 NULL NULL 20.03.1985 Wien 17.03.1985 Berlin
12 NULL NULL NULL NULL 25.11.1992 Hamburg

Mit

MAX(CASE WHEN BCode = 'P' THEN Ort ELSE NULL END) AS POrt

geht's ja nicht, weil dann Datum und Ort nicht zusammenpassen. Ich hab' mich
auch schon mit dem PIVOT Operator vom SQL Server 2005 gespielt, komm' damit
aber auch auf keinen grünen Zweig.

Hat jemand eine Idee, wie ich das lösen kann?

TIA

Grüße
Thomas

Grüße
Thomas

Any problem in computer science can be solved with another layer
of indirection. But that usually will create another problem.
David Wheeler
 

Lesen sie die antworten

#1 Hannes Brunner
13/05/2008 - 18:12 | Warnen spam
Hallo Thomas,

Thomas Schremser schrieb:
Hallo allerseits!

Ich habe folgende Tabelle:

CREATE TABLE Berechtigung
(
ID int NOT NULL PRIMARY KEY,
PersonID int NOT NULL,
BCode char(1) NOT NULL,
Ort varchar(100) NOT NULL,
Von datetime NOT NULL
)

Diese enthàlt Daten, die in etwa so aussehen:

ID PersonID BCode Ort Von
1 10 P Wien 24.01.1970
2 10 P Salzburg 07.05.1972
3 11 A Berlin 17.03.1985
4 11 N Wien 20.03.1985
5 12 A Hamburg 25.11.1992
6 10 D Wien 01.08.2007

Aus diesen Daten wird eine Pivot-Tabelle gebildet, die pro PersonID und Bdld
das höchste Datum je BCode für die Codes P, N, und A enthàlt:

SELECT PersonID,
MAX(CASE WHEN BCode = 'P' THEN Von ELSE NULL END) AS PVon,
MAX(CASE WHEN BCode = 'N' THEN Von ELSE NULL END) AS NVon,
MAX(CASE WHEN BCode = 'A' THEN Von ELSE NULL END) AS AVon
FROM Berechtigung
WHERE BCode IN('P', 'N', 'A')


GROUP BY PersonID


Dies ergibt

PersonID PVon NVon AVon
10 07.05.1972 NULL NULL
11 NULL 20.03.1985 17.03.1985
12 NULL NULL 25.11.1992

Soweit ist's ja noch kein Problem. Nun soll aber der jeweilige Ort
auch mit in die Pivot-Tabelle mit aufgenommen werden, also als Ergebnis
das Folgende herauskommen:

PersonID PVon POrt NVon NOrt AVon AOrt
10 07.05.1972 Salzburg NULL NULL NULL NULL
11 NULL NULL 20.03.1985 Wien 17.03.1985 Berlin
12 NULL NULL NULL NULL 25.11.1992 Hamburg



mein Vorschlag: Erst in einer abgeleiteten Tabelle die jeweils letzten
Vorgànge zu PersonID/BCode herausfiltern:

SELECT <dein Pivot-Konstrukt>
FROM (SELECT A.PersonID, A.BCode, A.Von, A.Ort
FROM Berechtigung AS A
WHERE A.BCode IN('P', 'N', 'A')
AND A.ID = (SELECT TOP 1 B.ID
FROM Berechtigung AS B
WHERE B.PersonID = A.PersonID
AND B.BCode = A.BCode
ORDER BY B.Von DESC)) AS C

Gruß
Hannes

Ähnliche fragen