没有简单的方法可以做到这一点,因为枢轴需要按列聚合。鉴于将列添加到输入表会导致维护问题,其中这些值不会出现在输出中,直到代码在任何使用的地方发生更改,我会说您最好使用存储过程执行一次,这将根据输入表的模式动态生成您正在寻找的输出。
我已经使用您提供的数据演示了如何做到这一点。此数据存储在临时表中(不是#temp,因为存储的过程不适用于临时表),填充如下:
CREATE TABLE temp (
_key int,
package_name varchar(50),
cost float,
included bit
)
INSERT INTO temp VALUES(1,'Package1', 10.00, 1)
INSERT INTO temp VALUES(2,'Package2', 20.00, 0)
INSERT INTO temp VALUES(3,'Package3', 20.00, 1)
存储过程根据@pivot_field 参数检索值列表,并将这些值用作要插入“类型”字段之后的列列表。然后,它将透视字段和所有其他字段联合在一起以生成行,一次旋转一列。程序如下:
CREATE PROCEDURE usp_get_pivot (@table_name nvarchar(255), @pivot_field nvarchar(255)) AS
BEGIN
CREATE TABLE #temp (val nvarchar(max))
DECLARE @sql NVARCHAR(MAX), @cols NVARCHAR(MAX), @col NVARCHAR(255)
SET @sql = 'SELECT DISTINCT ' + @pivot_field + ' FROM ' + @table_name
INSERT INTO #temp EXEC sp_executesql @sql;
SET @cols = (SELECT '[' + val + '],' FROM #temp FOR XML PATH(''))
SET @cols = SUBSTRING(@cols, 1, LEN(@cols)-1)
SET @SQL = N'SELECT ''' + @pivot_field + ''' as [type], *
FROM (SELECT ' + @pivot_field + ', ' + @pivot_field + ' as ' + @pivot_field + '1 FROM ' + @table_name + ') AS source_table
PIVOT (max(' + @pivot_field + '1) FOR ' + @pivot_field + ' IN (' + @cols + ')) AS pivot_table'
DECLARE csr CURSOR FOR
SELECT c.name FROM sys.columns c, sys.objects o
WHERE c.object_id = o.object_id AND o.name = @table_name
AND c.name <> @pivot_field
ORDER BY column_id
OPEN csr
FETCH NEXT FROM csr INTO @col
WHILE @@FETCH_STATUS = 0
BEGIN
SET @sql = @sql + ' UNION ALL
SELECT ''' + @col + ''' as [type], *
FROM (SELECT ' + @pivot_field + ', CAST(' + @col + ' AS VARCHAR) AS ' + @col + ' FROM ' + @table_name + ') AS source_table
PIVOT (max(' + @col + ') FOR ' + @pivot_field + ' IN (' + @cols + ')) AS pivot_table'
FETCH NEXT FROM csr INTO @col
END
CLOSE csr
DEALLOCATE csr
DROP TABLE #temp
EXEC sp_executesql @sql
END
您应该能够简单地将程序复制并粘贴到管理工作室,创建如上所示的数据并执行程序:
EXEC usp_get_pivot 'temp', 'package_name'