sql >> Base de Datos >  >> RDS >> Sqlserver

Cómo usar PIVOT en SQL Server 2005 Procedimiento almacenado Uniendo dos vistas

Necesita saber todos los valores posibles para PIVOT by. Por lo tanto, es difícil hacer esto con T-SQL directamente a menos que use SQL dinámico y esto puede complicarse bastante rápido. Probablemente sea mejor pasar todas las filas al nivel de presentación o al escritor de informes y dejar que las gire hacia los lados.

Aquí hay un ejemplo rápido de PIVOT si conoce todos los valores de UBCategory por adelantado. Omití ICCUDays porque parece bastante irrelevante a menos que haya columnas que provengan de esa vista como parte del resultado.

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;

Para hacer esto más dinámico, tendría que obtener la lista separada por comas de valores DISTINCT UBCategory y construir el pivote sobre la marcha. Así que podría verse así:

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;

Luego, para "enviar los datos a una nueva tabla", puede hacer que la consulta sea INSERTAR EN ... SELECCIONAR en lugar de SELECCIONAR directamente. Por supuesto, esto parece un poco inútil, porque para escribir esa declaración de inserción, necesita saber el orden de las columnas (que no está garantizado con este enfoque) y debe haber colocado columnas para cada UBCategory potencial valor de todos modos, por lo que esto parece muy gallina y huevo.