连接多个表 - 然后应用 PIVOT 以不同方式显示数据
Joining across several tables - then applying a PIVOT to display the data differently
我正在尝试寻找一种方法来执行看似复杂的连接方案,但不确定如何着手。
一些背景信息:
-我有一个 'ProjectCategory' table,其中包含一个外键 'ProjectID' 和 'CategoryID' 分别指向项目和类别 table。一个项目可以拥有与现有类别一样多的指定类别(最多 10 个)
-我有一个'Budget'table和一个'Sponsor'Table.
-我的 'Project' table 与我的 'Budget' Table 有关,因为所有项目都有关联的 BudgetID
-我的 'Budget' Table 与我的 'Sponser' table 有关,因为所有预算都有关联的 SponsorID。
-'Project' table 和 'Sponsor' table 没有直接关系。
首先我尝试获取的结果集示例是:
SponsorName(Field in sponsor table) - ProjectName - Category
___________________________________ ___________ ________
A ABC categoryA
A ABC categoryB
A DEF categoryX
A DEF categoryZ
然后我想使用 PIVOT 来显示如下数据:
SponsorName - ProjectName -categoryA - categoryB -categoryC - categoryD ...
___________ ___________ _________ _________ _________ _________
A ABC X X
A DEF X X
B EFG X X
X 标记每个 project/sponsor 组合与哪些类别相关联。 Xs 的填充可能是我将在代码隐藏或使用其他存储过程中做的事情,但这是我正在尝试做的事情的基本思想。
在我什至实现一个数据透视表以将其显示为第二组之前,我什至无法弄清楚如何编写查询以取回第一组,所以我有点被这个任务吓倒了。非常感谢任何帮助,如果您需要更多信息,请告诉我
假设 SQL 服务器,我对大部分动态 PIVOTS 使用存储过程。 (在下面列出)
源可以是 table、#temp 甚至 SQL
Exec [prc-Pivot] '#Temp','Category','max(''X'')[]','SponsorName,ProjectName',null
Returns
SponsorName ProjectName categoryA categoryB categoryD categoryX categoryZ
A ABC X X NULL NULL NULL
A DEF NULL NULL NULL X X
B EFG X NULL X NULL NULL
存储过程
CREATE PROCEDURE [dbo].[prc-Pivot] (
@Source varchar(1000), -- Any Table or Select Statement
@PvotCol varchar(250), -- Field name or expression ie. Month(Date)
@Summaries varchar(250), -- aggfunction(aggValue)[optionalTitle]
@GroupBy varchar(250), -- Optional additional Group By
@OtherCols varchar(500) ) -- Optional Group By or aggregates
AS
--Exec [prc-Pivot] 'Select Year=Year(TR_Date),* From [Chinrus-Series].[dbo].[DS_Treasury_Rates]','''Q''+DateName(QQ,TR_Date)','avg(TR_Y10)[-Avg]','Year','count(*)[Records],min(TR_Y10)[Min],max(TR_Y10)[Max],Avg(TR_Y10)[Avg]'
Set NoCount On
Set Ansi_Warnings Off
Declare @Vals varchar(max),@SQL varchar(max);
Set @Vals = ''
Set @OtherCols= IsNull(', ' + @OtherCols,'')
Set @Source = case when @Source Like 'Select%' then @Source else 'Select * From '+@Source end
Create Table #TempPvot (Pvot varchar(100))
Insert Into #TempPvot
Exec ('Select Distinct Convert(varchar(100),' + @PvotCol + ') as Pvot FROM (' + @Source + ') A')
Select @Vals = @Vals + ', isnull(' + Replace(Replace(@Summaries,'(','(CASE WHEN ' + @PvotCol + '=''' + Pvot + ''' THEN '),')[', ' END),NULL) As [' + Pvot ) From #TempPvot Order by Pvot
Drop Table #TempPvot
Set @SQL = Replace('Select ' + Isnull(@GroupBy,'') + @OtherCols + @Vals + ' From (' + @Source + ') PvtFinal ' + case when Isnull(@GroupBy,'')<>'' then 'Group By ' + @GroupBy + ' Order by ' + @GroupBy else '' end,'Select , ','Select ')
--Print @SQL
Exec (@SQL)
Set NoCount Off
Set Ansi_Warnings on
我正在尝试寻找一种方法来执行看似复杂的连接方案,但不确定如何着手。 一些背景信息:
-我有一个 'ProjectCategory' table,其中包含一个外键 'ProjectID' 和 'CategoryID' 分别指向项目和类别 table。一个项目可以拥有与现有类别一样多的指定类别(最多 10 个)
-我有一个'Budget'table和一个'Sponsor'Table.
-我的 'Project' table 与我的 'Budget' Table 有关,因为所有项目都有关联的 BudgetID
-我的 'Budget' Table 与我的 'Sponser' table 有关,因为所有预算都有关联的 SponsorID。
-'Project' table 和 'Sponsor' table 没有直接关系。
首先我尝试获取的结果集示例是:
SponsorName(Field in sponsor table) - ProjectName - Category
___________________________________ ___________ ________
A ABC categoryA
A ABC categoryB
A DEF categoryX
A DEF categoryZ
然后我想使用 PIVOT 来显示如下数据:
SponsorName - ProjectName -categoryA - categoryB -categoryC - categoryD ...
___________ ___________ _________ _________ _________ _________
A ABC X X
A DEF X X
B EFG X X
X 标记每个 project/sponsor 组合与哪些类别相关联。 Xs 的填充可能是我将在代码隐藏或使用其他存储过程中做的事情,但这是我正在尝试做的事情的基本思想。
在我什至实现一个数据透视表以将其显示为第二组之前,我什至无法弄清楚如何编写查询以取回第一组,所以我有点被这个任务吓倒了。非常感谢任何帮助,如果您需要更多信息,请告诉我
假设 SQL 服务器,我对大部分动态 PIVOTS 使用存储过程。 (在下面列出)
源可以是 table、#temp 甚至 SQL
Exec [prc-Pivot] '#Temp','Category','max(''X'')[]','SponsorName,ProjectName',null
Returns
SponsorName ProjectName categoryA categoryB categoryD categoryX categoryZ
A ABC X X NULL NULL NULL
A DEF NULL NULL NULL X X
B EFG X NULL X NULL NULL
存储过程
CREATE PROCEDURE [dbo].[prc-Pivot] (
@Source varchar(1000), -- Any Table or Select Statement
@PvotCol varchar(250), -- Field name or expression ie. Month(Date)
@Summaries varchar(250), -- aggfunction(aggValue)[optionalTitle]
@GroupBy varchar(250), -- Optional additional Group By
@OtherCols varchar(500) ) -- Optional Group By or aggregates
AS
--Exec [prc-Pivot] 'Select Year=Year(TR_Date),* From [Chinrus-Series].[dbo].[DS_Treasury_Rates]','''Q''+DateName(QQ,TR_Date)','avg(TR_Y10)[-Avg]','Year','count(*)[Records],min(TR_Y10)[Min],max(TR_Y10)[Max],Avg(TR_Y10)[Avg]'
Set NoCount On
Set Ansi_Warnings Off
Declare @Vals varchar(max),@SQL varchar(max);
Set @Vals = ''
Set @OtherCols= IsNull(', ' + @OtherCols,'')
Set @Source = case when @Source Like 'Select%' then @Source else 'Select * From '+@Source end
Create Table #TempPvot (Pvot varchar(100))
Insert Into #TempPvot
Exec ('Select Distinct Convert(varchar(100),' + @PvotCol + ') as Pvot FROM (' + @Source + ') A')
Select @Vals = @Vals + ', isnull(' + Replace(Replace(@Summaries,'(','(CASE WHEN ' + @PvotCol + '=''' + Pvot + ''' THEN '),')[', ' END),NULL) As [' + Pvot ) From #TempPvot Order by Pvot
Drop Table #TempPvot
Set @SQL = Replace('Select ' + Isnull(@GroupBy,'') + @OtherCols + @Vals + ' From (' + @Source + ') PvtFinal ' + case when Isnull(@GroupBy,'')<>'' then 'Group By ' + @GroupBy + ' Order by ' + @GroupBy else '' end,'Select , ','Select ')
--Print @SQL
Exec (@SQL)
Set NoCount Off
Set Ansi_Warnings on