Wykonałem następującą procedurę dynamicznego obracania wszystkich wartości w tabeli.
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
Zastosowanie:
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
udało mi się uzyskać elastyczność Chciałem budując moje poglądy za pomocą przegubu() w przechowywanej proc, które mogą być zaplanowane do odtworzenia poglądy w razie potrzeby. Daj mi znać, jeśli ktoś chce PROC. –