Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment utiliser PIVOT dans SQL Server 2005 Procédure stockée Joindre deux vues

Vous devez connaître toutes les valeurs possibles pour effectuer PIVOT. Il est donc difficile de le faire directement avec T-SQL à moins que vous n'utilisiez du SQL dynamique et cela peut devenir assez rapidement poilu. Il est probablement préférable de transmettre toutes les lignes au niveau de la présentation ou au rédacteur du rapport et de le laisser les tourner sur le côté.

Voici un exemple rapide de PIVOT si vous connaissez à l'avance toutes les valeurs UBCategory. J'ai omis ICCUDays car cela semble plutôt hors de propos à moins qu'il n'y ait des colonnes qui proviennent de cette vue dans le cadre du résultat.

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;

Pour rendre cela plus dynamique, vous devez obtenir la liste séparée par des virgules des valeurs DISTINCT UBCategory et créer le pivot à la volée. Cela pourrait donc ressembler à ceci :

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;

Ensuite, pour "envoyer les données vers une nouvelle table", vous pouvez simplement faire de la requête un INSERT INTO ... SELECT au lieu d'un SELECT direct. Bien sûr, cela semble un peu inutile, car pour écrire cette instruction d'insertion, vous devez connaître l'ordre des colonnes (ce qui n'est pas garanti avec cette approche) et vous devez déjà avoir mis des colonnes pour chaque UBCategory potentiel valeur de toute façon, donc cela semble très poulet et œuf.