Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Come utilizzare PIVOT nella stored procedure di SQL Server 2005 che unisce due viste

È necessario conoscere tutti i valori possibili per PIVOT di. Quindi è difficile farlo direttamente con T-SQL a meno che non usi SQL dinamico e questo può diventare peloso abbastanza rapidamente. Probabilmente è meglio riportare tutte le righe al livello di presentazione o allo scrittore del rapporto e lasciarle girare di lato.

Ecco un rapido esempio PIVOT se conosci tutti i valori di UBCategory in anticipo. Ho omesso ICCUDays poiché sembra piuttosto irrilevante a meno che non ci siano colonne che provengono da quella vista come parte del risultato.

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;

Per renderlo più dinamico, dovresti ottenere l'elenco separato da virgole dei valori DISTINCT UBCategory e costruire il pivot al volo. Quindi potrebbe assomigliare a questo:

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;

Quindi per "inviare i dati a una nuova tabella" puoi semplicemente rendere la query un INSERT INTO ... SELECT invece di un SELECT diretto. Ovviamente, questo sembra un po' inutile, perché per scrivere quell'istruzione insert, devi conoscere l'ordine delle colonne (che non è garantito con questo approccio) e devi aver già inserito colonne per ogni potenziale UBCategory valore comunque, quindi questo sembra molto pollo e uovo.