【问题标题】:Converting SQL pivot table to T-SQL for Report Builder 3.0将 SQL 数据透视表转换为 Report Builder 3.0 的 T-SQL
【发布时间】:2016-11-24 14:17:40
【问题描述】:

将一个相当冗长的 SQL 数据透视表数据集导入到 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

【问题讨论】:

  • 能否请您发布架构和一些测试数据FullPanellistEligibilityView?这实际上看起来像一个非常简单的查询,但它比它需要的复杂得多。

标签: sql sql-server tsql reporting-services reportbuilder3.0


【解决方案1】:

为了设置数据驱动的参数选择,您需要做两件事。

首先,您需要创建一个数据集来填充您的参数下拉菜单。这需要以正确的顺序列出您希望用户能够选择的所有值。这可以为显示给用户的标签和传递给查询的值返回一列:

select distinct PanelCode       -- Parameter Value
                ,PanelName      -- Parameter Label
from FullPanellistEligibilityView
order by PanelName

创建一个参数并设置此数据集的可用值,并为LabelValue 属性使用适当的列。

其次,您需要向数据集添加过滤器。我冒昧地重写了您上面的查询,以使用派生表/公用表表达式/cte 而不是您的PIVOT。下面的代码包含对 SSRS 参数的引用,该参数将在选择后插入参数的“值”。这段代码显然没有经过测试,因为我没有你的架构,但设计应该很容易理解:

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

【讨论】:

  • 太棒了,已经清楚了很多,我现在需要冲刺,但会在星期一测试这个。谢谢戴夫!
  • @I'mInWayOverMyHead 不用担心!您需要注意的是,您和我的查询都不能处理有 no 名合格小组成员的小组。在这种情况下,面板根本不会被退回。
  • 谢谢戴夫,这已经成功了。我过去主要在 Microsoft Access 中工作,因此我需要重新考虑堆叠查询的方式以获得所需的输出。
猜你喜欢
  • 1970-01-01
  • 2012-07-24
  • 2014-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多