Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Verwendung von PIVOT in SQL Server 2005 Stored Procedure Joining Two Views

Sie müssen alle möglichen Werte für PIVOT kennen. Daher ist es schwierig, dies direkt mit T-SQL zu tun, es sei denn, Sie verwenden dynamisches SQL, und dies kann ziemlich schnell haarig werden. Es ist wahrscheinlich besser, alle Zeilen an die Präsentationsebene oder den Berichtersteller zurückzugeben und sie seitlich drehen zu lassen.

Hier ist ein kurzes PIVOT-Beispiel, wenn Sie alle UBCategory-Werte im Voraus kennen. Ich habe ICCUDays ausgelassen, da es eher irrelevant erscheint, es sei denn, es gibt Spalten, die aus dieser Ansicht als Teil des Ergebnisses stammen.

USE tempdb;
GO
SET NOCOUNT ON;
GO

-- who on earth is responsible for your naming scheme?
CREATE TABLE dbo.ICCUEnctrSelectedRevCatsDirCost
(
    Account INT,
    UBCategory VARCHAR(10),
    DirectCost DECIMAL(9,2)
);

INSERT dbo.ICCUEnctrSelectedRevCatsDirCost
    SELECT 1, 'foo', 5.25
    UNION SELECT 1, 'bar', 6.25
    UNION SELECT 1, 'smudge', 8.50
    UNION SELECT 2, 'foo', 9.25
    UNION SELECT 2, 'brap', 2.75;

SELECT Account,[foo],[bar],[smudge],[brap] FROM 
    dbo.ICCUEnctrSelectedRevCatsDirCost
    -- WHERE <something>, I assume ???
PIVOT
(
    MAX(DirectCost)
    FOR UBCategory IN ([foo],[bar],[smudge],[brap])
) AS p;

GO
DROP TABLE dbo.ICCUEnctrSelectedRevCatsDirCost;

Um dies dynamischer zu gestalten, müssten Sie die durch Kommas getrennte Liste der DISTINCT UBCategory-Werte abrufen und den Pivot on the fly erstellen. Es könnte also so aussehen:

USE tempdb;
GO
SET NOCOUNT ON;
GO

-- who on earth is responsible for your naming scheme?
CREATE TABLE dbo.ICCUEnctrSelectedRevCatsDirCost
(
    Account INT,
    UBCategory VARCHAR(10),
    DirectCost DECIMAL(9,2)
);

INSERT dbo.ICCUEnctrSelectedRevCatsDirCost
    SELECT 1, 'foo', 5.25
    UNION SELECT 1, 'bar', 6.25
    UNION SELECT 1, 'smudge', 8.50
    UNION SELECT 2, 'foo', 9.25
    UNION SELECT 2, 'brap', 2.75
    UNION SELECT 3, 'bingo', 4.00;

DECLARE @sql NVARCHAR(MAX),
    @col NVARCHAR(MAX);

SELECT @col = COALESCE(@col, '') + QUOTENAME(UBCategory) + ','
    FROM 
    (
        SELECT DISTINCT UBCategory
        FROM dbo.ICCUEnctrSelectedRevCatsDirCost
    ) AS x;

SET @col = LEFT(@col, LEN(@col)-1);

SET @sql = N'SELECT Account, $col$ FROM 
    dbo.ICCUEnctrSelectedRevCatsDirCost
    -- WHERE <something>, I assume ???
PIVOT
(
    MAX(DirectCost)
    FOR UBCategory IN ($col$)
) AS p;';

SET @sql = REPLACE(@sql, '$col$', @col);

--EXEC sp_executeSQL @sql;
PRINT @sql;

GO
DROP TABLE dbo.ICCUEnctrSelectedRevCatsDirCost;

Um dann "die Daten an eine neue Tabelle zu senden", können Sie die Abfrage einfach zu einem INSERT INTO ... SELECT anstelle eines direkten SELECT machen. Das erscheint natürlich irgendwie nutzlos, denn um diese Einfügeanweisung zu schreiben, müssen Sie die Reihenfolge der Spalten kennen (was bei diesem Ansatz nicht garantiert ist) und Sie müssen bereits Spalten für jede potenzielle UBCategory eingefügt haben Wert sowieso, also scheint das sehr Huhn und Ei zu sein.