如果我们把 marc_s 的答案放到一个过程中,我们有这样的:
create procedure spPivot (
@DataSource varchar(max),
@Column1 varchar(100),
@PivotColumn varchar(100),
@AggregateColumn varchar(100),
@AgregateFunction varchar(20),
@Debug bit = 0) as
declare @SQL varchar(max) =
'DECLARE @Columns as VARCHAR(MAX)
SELECT @Columns = COALESCE(@Columns + '', '','''') + QUOTENAME({PivotColumn})
FROM (SELECT DISTINCT {PivotColumn} FROM {DataSourceA} ds) c
ORDER BY {PivotColumn}
DECLARE @SQL as VARCHAR(MAX)
SET @SQL = ''SELECT {Column1}, '' + @Columns + ''
FROM {DataSourceB} as PivotData
PIVOT (
{AgregateFunction}({AggregateColumn})
FOR {PivotColumn} IN ('' + @Columns + '')
) AS PivotResult
ORDER BY {Column1}''
EXEC(@SQL)'
if @DataSource like 'select %' begin
set @SQL = replace(@SQL, '{DataSourceA}', '(' + @DataSource + ')')
set @SQL = replace(@SQL, '{DataSourceB}', '(' + replace(@DataSource, '''', '''''') + ')')
end else begin
set @SQL = replace(@SQL, '{DataSourceA}', @DataSource)
set @SQL = replace(@SQL, '{DataSourceB}', @DataSource)
end
set @SQL = replace(@SQL, '{Column1}', @Column1)
set @SQL = replace(@SQL, '{PivotColumn}', @PivotColumn)
set @SQL = replace(@SQL, '{AggregateColumn}', @AggregateColumn)
set @SQL = replace(@SQL, '{AgregateFunction}', @AgregateFunction)
if @Debug = 1
print @SQL
else
exec(@SQL)
及其用法示例:
spPivot
'select ''Bucket'' Category, ''Large'' SubCategory, 1 Amount union all
select ''Bucket'' Category, ''Large'' SubCategory, 2 Amount union all
select ''Shovel'' Category, ''Large'' SubCategory, 4 Amount union all
select ''Shovel'' Category, ''Small'' SubCategory, 8 Amount',
'Category', 'SubCategory', 'Amount', 'sum'
该示例有效,但请注意,将 [temp] 表的名称发送给过程可能更有效,因为它在其中被查询了两次。所以使用 marc_s 的临时表,调用将是
spPivot 'TEMP', '[Month]', 'Site', 'Val', 'SUM'
还请注意,您有一个 @debug 参数,您可以使用该参数来找出您的调用未按预期工作的原因。