将 Report Builder 3.0 的 SQL 数据透视表 table 转换为 T-SQL
Converting SQL pivot table to T-SQL for Report Builder 3.0
我一直有一点麻烦将一个相当冗长的 SQL pivot table 数据集导入到 SQL Server Report Builder 3.0 中,其格式允许我添加报告结果的参数。我知道这要求查询是 T-SQL 友好的
如果有帮助的话,上下文是我正在构建一份报告以查看各种市场研究小组的资格状态,我希望能够提供一个下拉菜单让用户在面板之间轻弹。所以结束 @parameter
将在 PanelCode
/ PanelName
上。这是一个复合查询:
SELECT
ELT.PanelCode,
ELR.PanelName,
ELR.Year,
ELT.PeriodType,
ELT.PeriodValue,
ELT.TotalPanelists,
ELT.EligiblePanelists,
ELR.TotalEligible,
ELR.TotalVacation,
ELR.TotalExcused,
ELR.TotalInactive,
ELR.TotalConnection,
ELR.TotalCompliance
FROM --the Ineligibility Reason Pivot Table (ELR)
(SELECT
PanelCode,
PanelName,
Year,
PeriodType,
PeriodValue,
Max([Eligible]) as TotalEligible,
Max([Vacation]) as TotalVacation,
Max([Excuse]) as TotalExcused,
Max([Inactive]) as TotalInactive,
Max([Connection]) as TotalConnection,
Max([Compliance]) as TotalCompliance
FROM
(SELECT
PanelCode,
PanelName,
Year,
PeriodType,
PeriodValue,
EligibilityFailureReason,
FROM FullPanellistEligibilityView) FPR
Pivot
(count(EligibilityFailureReason) FOR EligibilityFailureReason IN ([Eligible], [Vacation], [Excuse], [Inactive], [Connection], [Compliance])) AS PVT
WHERE PeriodType <> '4 week period' and Year > 2012
GROUP BY PanelCode, PanelName, PeriodType, Year, PeriodValue) as ELR
, -- And the Eligibility Totals Query, ELT
(
SELECT
PanelCode,
PanelName,
Year,
PeriodType,
PeriodValue,
Count(Poll1s) as TotalPanelists,
Sum(Poll1s) as EligiblePanelists
FROM
(SELECT
PanelCode,
PanelName,
Year
PeriodType,
PeriodValue,
CAST(isEligible as INT) as Poll1s
FROM FullPanellistEligibilityView) FPR
GROUP BY PanelCode, PeriodType, PeriodValue) ELT
WHERE (ELT.PeriodValue=ELR.PeriodValue) and (ELT.PanelCode=ELR.PanelCode)
我一直在努力寻找在线资源,这些资源建议如何在 Report Builder 3 中进行更大的查询并使它们可参数化。除了 WHERE PanelName = @PanelName
之外,我还需要添加什么才能做到这一点运行?
EDIT1:我不怀疑我已经使这个查询变得比必要的复杂得多,我是自学的。模式并不是真正必要的,因为所有这些数据都是从一个单一的、已经存在的视图 FullPanellistEligibilityView
中提取的,示例数据,从视图中剥离和模拟, can be found here
要设置数据驱动参数,您需要做两件事 selection。
首先,您需要创建一个数据集来填充参数下拉菜单。这需要以正确的顺序列出您希望用户能够 select 的所有值。这可以 return 一列显示给用户的标签和传递给查询的值:
select distinct PanelCode -- Parameter Value
,PanelName -- Parameter Label
from FullPanellistEligibilityView
order by PanelName
创建一个参数并为此数据集设置可用值,并为 Label
和 Value
属性使用适当的列。
其次,您需要向数据集添加过滤器。我冒昧地重写了您上面的查询,以使用派生的 table/common table expression/cte 而不是您的 PIVOT
。下面的代码包括对 SSRS 参数的引用,该参数将在 selected 后为参数插入 'Value'。这段代码显然没有经过测试,因为我没有你的架构,但设计应该很容易理解:
with t
as
(
select PanelCode
,PeriodValue
,count(isEligible) as TotalPanelists -- I'm assuming this is a BIT column, in which case it shouldn't have any null values. If it does, you will need to handle this with count(isnull(isEligible,0))
,Sum(CAST(isEligible as INT)) as EligiblePanelists
from FullPanellistEligibilityView
where PanelCode = @PanelCode -- This will filter your data due to the INNER JOIN below.
group by PanelCode
,PeriodType
,PeriodValue
)
select e.PanelCode
,e.PanelName
,e.Year
,e.PeriodType
,e.PeriodValue
,t.TotalPanelists
,t.EligiblePanelists
,sum(case when e.EligibilityFailureReason = 'Eligible' then 1 else 0 end) as TotalEligible,
,sum(case when e.EligibilityFailureReason = 'Vacation' then 1 else 0 end) as TotalVacation,
,sum(case when e.EligibilityFailureReason = 'Excuse' then 1 else 0 end) as TotalExcused,
,sum(case when e.EligibilityFailureReason = 'Inactive' then 1 else 0 end) as TotalInactive,
,sum(case when e.EligibilityFailureReason = 'Connection' then 1 else 0 end) as TotalConnection,
,sum(case when e.EligibilityFailureReason = 'Compliance' then 1 else 0 end) as TotalCompliance
from FullPanellistEligibilityView e
inner join t
on(e.PanelCode = t.PanelValue
and e.PeriodValue = t.PeriodValue
)
where e.PeriodType <> '4 week period'
and e.Year > 2012
group by e.PanelCode
,e.PanelName
,e.Year
,e.PeriodType
,e.PeriodValue
,t.TotalPanelists
,t.EligiblePanelists
我一直有一点麻烦将一个相当冗长的 SQL pivot table 数据集导入到 SQL Server Report Builder 3.0 中,其格式允许我添加报告结果的参数。我知道这要求查询是 T-SQL 友好的
如果有帮助的话,上下文是我正在构建一份报告以查看各种市场研究小组的资格状态,我希望能够提供一个下拉菜单让用户在面板之间轻弹。所以结束 @parameter
将在 PanelCode
/ PanelName
上。这是一个复合查询:
SELECT
ELT.PanelCode,
ELR.PanelName,
ELR.Year,
ELT.PeriodType,
ELT.PeriodValue,
ELT.TotalPanelists,
ELT.EligiblePanelists,
ELR.TotalEligible,
ELR.TotalVacation,
ELR.TotalExcused,
ELR.TotalInactive,
ELR.TotalConnection,
ELR.TotalCompliance
FROM --the Ineligibility Reason Pivot Table (ELR)
(SELECT
PanelCode,
PanelName,
Year,
PeriodType,
PeriodValue,
Max([Eligible]) as TotalEligible,
Max([Vacation]) as TotalVacation,
Max([Excuse]) as TotalExcused,
Max([Inactive]) as TotalInactive,
Max([Connection]) as TotalConnection,
Max([Compliance]) as TotalCompliance
FROM
(SELECT
PanelCode,
PanelName,
Year,
PeriodType,
PeriodValue,
EligibilityFailureReason,
FROM FullPanellistEligibilityView) FPR
Pivot
(count(EligibilityFailureReason) FOR EligibilityFailureReason IN ([Eligible], [Vacation], [Excuse], [Inactive], [Connection], [Compliance])) AS PVT
WHERE PeriodType <> '4 week period' and Year > 2012
GROUP BY PanelCode, PanelName, PeriodType, Year, PeriodValue) as ELR
, -- And the Eligibility Totals Query, ELT
(
SELECT
PanelCode,
PanelName,
Year,
PeriodType,
PeriodValue,
Count(Poll1s) as TotalPanelists,
Sum(Poll1s) as EligiblePanelists
FROM
(SELECT
PanelCode,
PanelName,
Year
PeriodType,
PeriodValue,
CAST(isEligible as INT) as Poll1s
FROM FullPanellistEligibilityView) FPR
GROUP BY PanelCode, PeriodType, PeriodValue) ELT
WHERE (ELT.PeriodValue=ELR.PeriodValue) and (ELT.PanelCode=ELR.PanelCode)
我一直在努力寻找在线资源,这些资源建议如何在 Report Builder 3 中进行更大的查询并使它们可参数化。除了 WHERE PanelName = @PanelName
之外,我还需要添加什么才能做到这一点运行?
EDIT1:我不怀疑我已经使这个查询变得比必要的复杂得多,我是自学的。模式并不是真正必要的,因为所有这些数据都是从一个单一的、已经存在的视图 FullPanellistEligibilityView
中提取的,示例数据,从视图中剥离和模拟, can be found here
要设置数据驱动参数,您需要做两件事 selection。
首先,您需要创建一个数据集来填充参数下拉菜单。这需要以正确的顺序列出您希望用户能够 select 的所有值。这可以 return 一列显示给用户的标签和传递给查询的值:
select distinct PanelCode -- Parameter Value
,PanelName -- Parameter Label
from FullPanellistEligibilityView
order by PanelName
创建一个参数并为此数据集设置可用值,并为 Label
和 Value
属性使用适当的列。
其次,您需要向数据集添加过滤器。我冒昧地重写了您上面的查询,以使用派生的 table/common table expression/cte 而不是您的 PIVOT
。下面的代码包括对 SSRS 参数的引用,该参数将在 selected 后为参数插入 'Value'。这段代码显然没有经过测试,因为我没有你的架构,但设计应该很容易理解:
with t
as
(
select PanelCode
,PeriodValue
,count(isEligible) as TotalPanelists -- I'm assuming this is a BIT column, in which case it shouldn't have any null values. If it does, you will need to handle this with count(isnull(isEligible,0))
,Sum(CAST(isEligible as INT)) as EligiblePanelists
from FullPanellistEligibilityView
where PanelCode = @PanelCode -- This will filter your data due to the INNER JOIN below.
group by PanelCode
,PeriodType
,PeriodValue
)
select e.PanelCode
,e.PanelName
,e.Year
,e.PeriodType
,e.PeriodValue
,t.TotalPanelists
,t.EligiblePanelists
,sum(case when e.EligibilityFailureReason = 'Eligible' then 1 else 0 end) as TotalEligible,
,sum(case when e.EligibilityFailureReason = 'Vacation' then 1 else 0 end) as TotalVacation,
,sum(case when e.EligibilityFailureReason = 'Excuse' then 1 else 0 end) as TotalExcused,
,sum(case when e.EligibilityFailureReason = 'Inactive' then 1 else 0 end) as TotalInactive,
,sum(case when e.EligibilityFailureReason = 'Connection' then 1 else 0 end) as TotalConnection,
,sum(case when e.EligibilityFailureReason = 'Compliance' then 1 else 0 end) as TotalCompliance
from FullPanellistEligibilityView e
inner join t
on(e.PanelCode = t.PanelValue
and e.PeriodValue = t.PeriodValue
)
where e.PeriodType <> '4 week period'
and e.Year > 2012
group by e.PanelCode
,e.PanelName
,e.Year
,e.PeriodType
,e.PeriodValue
,t.TotalPanelists
,t.EligiblePanelists