2010-12-29 14 views
8

Ich habe eine Tabelle, die Attribute basierend auf einem Schlüsselwert hat. Beispiel:SQL Server PIVOT auf Schlüsselwerttabelle

CREATE TABLE ObjectAttributes 
(
    int objectId, key nvarchar(64), value nvarchar(512) 
) 

Als ich von diesem wählen erhalte ich:

objectId key  value 
---------------------------- 
1   Key 1 Value 1 
1   Key 2 Value 2 

ich mich gefragt, ob ich die PIVOT Syntax dies wiederum in verwenden:

objectId Key 1  Key 2 
--------------------------- 
1   Value 1 Value 2 

Ich weiß, alle Meine Tische haben die gleichen Schlüssel. (Leider kann ich die Tabellenstruktur nicht einfach ändern. Das ist der Grund, warum ich PIVOTS verwenden möchte).

Das große Problem hier ist jedoch, dass Pivots erfordern eine Aggregationsfunktion verwendet werden. Gibt es eine Möglichkeit, dies abzuwenden? Tue ich es völlig falsch, dies zu versuchen? Oder gibt es eine bessere Lösung?

+0

Möchten Sie eine feste Spaltenausgabe? Das heißt, Sie möchten alle Schlüssel für die angegebene Objekt-ID drehen? – gbn

Antwort

7

Ein Pivot wird nicht schneller sein als wiederholte Self Joins für eine feste Spaltenausgabe.

SELECT 
    T1.objectID, T1.Value AS Key1, T2.Value AS Key2 
FROM 
    ObjectAttributes T1 
    JOIN 
    ObjectAttributes T2 ON T1.objectID = T2.objectID 
WHERE 
    T1.key = 'Key 1' 
    AND 
    T2.key = 'Key 2' 

Wenn Sie PIVOT verwenden möchten, verwenden Sie einfach MAX. Da Sie pro Objekt/Schlüssel eine Zeile haben, ist es sowieso trivial und erfüllt die PIVOT-Anforderung.

Wenn Sie eine unbekannte Anzahl von Zeilen in Spalten PIVOTIEREN möchten, dann ist es dynamische SQL (wie SQL Server 2000-Lösungen) oder tun es im Client-Code.

Wenn jedes Objekt eine feste Anzahl von Attributen hat, würde ich eine zweite Tabelle mit echten Spalten, die von einem Trigger verwaltet werden, in Erwägung ziehen. Tollpatschig, aber macht das Leben leichter zum Lesen

+0

Ah ok. Ich nahm an, dass der Pivot-Tisch eine Art Magie hinter sich hatte, die es schneller machte. Ich werde nur mit der Self-Join-Route gehen. – Kyle

+0

Möglicherweise möchten Sie Outer-Joins für diese Lösung verwenden. Wenn Sie einen Schlüssel verpassen, verschwindet die gesamte Zeile der Ausgabe-Objekt-IDs mit den hier verwendeten inneren Joins. –

+0

@Sir Wobin: und verschiebe den Filter auch auf den JOIN ... – gbn

5

Nein, Sie können das Aggregat nicht vermeiden. SQL Server benötigt eine Möglichkeit, die vielen möglichen Zeilen in einem Wert zu kombinieren. Sie haben zufällig einen Wert, aber die PIVOT Funktionalität ist mit vielen Zeilen im Hinterkopf gemacht.

SELECT objectId, [Key 1], [Key 2] 
FROM 
(SELECT objectId, [key], value FROM ObjectAttributes) AS source 
PIVOT 
(
MIN(value) 
FOR [key] IN ([Key 1], [Key 2]) 
) as pvt