这里有一个解决方案。我正在使用存储过程。主源表 DeptBudget 有各种列,例如用户、日期等,但我使用的列是 Status、HR_Budget 和 IT_Budget。我正在使用 9 种可能的状态,但可以修改更多。最好的部分是我不必知道状态的值!解决方案的关键是使用和 Identity 作为数据透视字段,然后根据需要重命名列并删除。无需动态 SQL!
-- STEP 1: Declare Column Name Variable
Declare @tnc varchar(50)
-- STEP 2: Create 2 temporay tables #StageA and #StageB.
CREATE TABLE #StageA (
ID int IDENTITY(1,1) NOT NULL,
Budget varchar(50),
HR_Budget decimal(12,2),
IT_Budget decimal(12,2)
)
CREATE TABLE #StageB (
Budget varchar(50),
[1] decimal(12,2),
[2] decimal(12,2),
[3] decimal(12,2),
[4] decimal(12,2),
[5] decimal(12,2),
[6] decimal(12,2),
[7] decimal(12,2),
[8] decimal(12,2),
[9] decimal(12,2)
)
-- STEP 3: Dump Aggregated data into #StageA
INsert Into #StageA (Budget, HR_Budget, IT_Budget)
Select [Status], Sum(HR_Budget), Sum(IT_Budget)
From DeptBudget
Group By [Status]
-- STEP 4: Pivot into #StageB
Insert into #StageB
Select Budget, SUM([1]) AS [1],SUM([2]) AS [2],SUM([3]) AS [3],SUM([4]) AS [4],SUM([5]) AS [5],SUM([6]) AS [6]
,SUM([7]) AS [7],SUM([8]) AS [8],SUM([9]) AS [9]
from
(
Select 'IT Budget' As Budget, ISNULL([1], 0) AS [1],ISNULL([2], 0) AS [2],ISNULL([3], 0) AS [3],ISNULL([4], 0) AS [4],ISNULL([5], 0) AS [5],ISNULL([6], 0) AS [6]
,ISNULL([7], 0) AS [7],ISNULL([8], 0) AS [8],ISNULL([9], 0) AS [9]
from
(
Select ID, IT_Budget From #StageA
)
pvt
Pivot
(
Sum(IT_Budget) for [ID] in ([1],[2],[3],[4],[5],[6],[7],[8],[9])
)
Pvttab
Union
Select 'HR Budget' As Budget, ISNULL([1], 0) AS [1],ISNULL([2], 0) AS [2],ISNULL([3], 0) AS [3],ISNULL([4], 0) AS [4],ISNULL([5], 0) AS [5],ISNULL([6], 0) AS [6]
,ISNULL([7], 0) AS [7],ISNULL([8], 0) AS [8],ISNULL([9], 0) AS [9]
from
(
Select ID, HR_Budget From #StageA
)
pvt
Pivot
(
Sum(HR_Budget) for [ID] in ([1],[2],[3],[4],[5],[6],[7],[8],[9])
)
Pvttab
Union
Select 'Total Budget' As Budget, ISNULL([1], 0) AS [1],ISNULL([2], 0) AS [2],ISNULL([3], 0) AS [3],ISNULL([4], 0) AS [4],ISNULL([5], 0) AS [5],ISNULL([6], 0) AS [6]
,ISNULL([7], 0) AS [7],ISNULL([8], 0) AS [8],ISNULL([9], 0) AS [9]
from
(
Select ID, HR_Budget + IT_Budget AS BudgetTotal From #StageA
)
pvt
Pivot
(
Sum(BudgetTotal) for [ID] in ([1],[2],[3],[4],[5],[6],[7],[8],[9])
)
Pvttab
) pVS
Group By Budget
-- STEP 5: Rename The Columns and drop those not needed.
select @tnc = Null
Select @tnc = Budget From #StageA Where ID=1
If @tnc IS Not NUll
Begin
EXEC tempdb..sp_rename '#StageB.[1]', @tnc, 'COLUMN'
End
Else
Begin
ALTER TABLE #StageB
DROP COLUMN [1];
End
select @tnc = Null
Select @tnc = Budget From #StageA Where ID=2
If @tnc IS Not NUll
Begin
EXEC tempdb..sp_rename '#StageB.[2]', @tnc, 'COLUMN'
End
Else
Begin
ALTER TABLE #StageB
DROP COLUMN [2];
End
select @tnc = Null
Select @tnc = Budget From #StageA Where ID=3
If @tnc IS Not NUll
Begin
EXEC tempdb..sp_rename '#StageB.[3]', @tnc, 'COLUMN'
End
Else
Begin
ALTER TABLE #StageB
DROP COLUMN [3];
End
select @tnc = Null
Select @tnc = Budget From #StageA Where ID=4
If @tnc IS Not NUll
Begin
EXEC tempdb..sp_rename '#StageB.[4]', @tnc, 'COLUMN'
End
Else
Begin
ALTER TABLE #StageB
DROP COLUMN [4];
End
select @tnc = Null
Select @tnc = Budget From #StageA Where ID=5
If @tnc IS Not NUll
Begin
EXEC tempdb..sp_rename '#StageB.[5]', @tnc, 'COLUMN'
End
Else
Begin
ALTER TABLE #StageB
DROP COLUMN [5];
End
select @tnc = Null
Select @tnc = Budget From #StageA Where ID=6
If @tnc IS Not NUll
Begin
EXEC tempdb..sp_rename '#StageB.[6]', @tnc, 'COLUMN'
End
Else
Begin
ALTER TABLE #StageB
DROP COLUMN [6];
End
select @tnc = Null
Select @tnc = Budget From #StageA Where ID=7
If @tnc IS Not NUll
Begin
EXEC tempdb..sp_rename '#StageB.[7]', @tnc, 'COLUMN'
End
Else
Begin
ALTER TABLE #StageB
DROP COLUMN [7];
End
select @tnc = Null
Select @tnc = Budget From #StageA Where ID=8
if @tnc IS Not NUll
Begin
EXEC tempdb..sp_rename '#StageB.[8]', @tnc, 'COLUMN'
End
Else
Begin
ALTER TABLE #StageB
DROP COLUMN [8];
End
select @tnc = Null
Select @tnc = Budget From #StageA Where ID=9
If @tnc IS Not NUll
Begin
EXEC tempdb..sp_rename '#StageB.[9]', @tnc, 'COLUMN'
End
Else
Begin
ALTER TABLE #StageB
DROP COLUMN [9];
End
-- Show The Data
Select * From #StageB