Realicé el siguiente procedimiento para pivotar dinámicamente todos los valores en una tabla.
CREATE OR ALTER PROC dbo.spDynamicPivot (
@Query NVARCHAR(MAX) --The query to pivot
, @AggregateFunction NVARCHAR(MAX) --The aggregation function surrounding the column name to be pivoted
, @ValueColumn NVARCHAR(MAX) --The value column from which to create columns
, @ResultTable NVARCHAR(MAX) = NULL --An optional table name into which the results will be stored. Note, this unfortunately will not work with #temp tables.
) AS BEGIN
SET XACT_ABORT ON;
SET NOCOUNT ON;
DECLARE @cols NVARCHAR(MAX);
DECLARE @sql NVARCHAR(MAX) = 'SELECT @cols = ISNULL(@cols + '','', '''') + ''['' + Val + '']'' FROM (SELECT DISTINCT Val = ' + @ValueColumn + ' FROM (' + @Query + ') a) b;';
DECLARE @paramDef NVARCHAR(MAX) = '@cols NVARCHAR(MAX) OUTPUT';
EXEC sp_executesql @sql, @paramDef, @cols = @cols OUTPUT;
DECLARE @resultSetSql NVARCHAR(MAX) = IIF(ISNULL(@ResultTable, '') <> '', 'INTO ' + @ResultTable + ' ', '');
SET @sql = 'SELECT * ' + @resultSetSql + 'FROM (' + @Query + ') q PIVOT(' + @AggregateFunction + ' FOR ' + @ValueColumn + ' IN (' + @cols + ')) p';
EXEC sp_executesql @sql;
END
Uso:
DROP TABLE IF EXISTS #t;
CREATE TABLE #t (Name VARCHAR(50), Age INT, NetWorth FLOAT);
INSERT INTO #t VALUES
('Bill', 50, 250),
('Barb', 17, 15),
('Fred', 25, 30),
('Bill', 25, 100),
('Kahless', 90000, 4E10)
--Displaying results directly
EXEC dbo.spDynamicPivot @Query = 'SELECT * FROM #t', @AggregateFunction = 'AVG(NetWorth)', @ValueColumn = 'Name'
--Or writing them into a table for additional use
DROP TABLE IF EXISTS tempdb.dbo.MyTable;
EXEC dbo.spDynamicPivot @Query = 'SELECT * FROM #t', @AggregateFunction = 'AVG(NetWorth)', @ValueColumn = 'Name', @ResultTable = 'tempdb.dbo.MyTable'
SELECT * FROM tempdb.dbo.MyTable
He conseguido que la flexibilidad que quería mediante la construcción de mis puntos de vista (usando pivote) en un procedimiento almacenado que puede ser programado para reproducir las vistas cuando sea necesario. Avíseme si alguien quiere el PROC. –