我可以通过动态调整的表格在SSRS中制作Tablix报告吗?

时间:2017-09-14 17:01:29

标签: sql-server visual-studio reporting-services

我的查询结果是透视表,从当前月份和总金额开始显示12个月。月份是动态的,因此10月份表格中的第一列将是11月,最后一列将是10月(当前一列)。

enter image description here

如何使用此结果集创建简单的Tablix或矩阵?我主要关注的是如何在Tablix中创建动态月份名称?

这甚至可能吗?

enter image description here  UPDATE:

我将列重命名为1到12之间的值。但是当我尝试编写10月份的表达式时,例如:=Month(Today()) - CInt(Fields!ID10.Value)它只是给我一个当前月份编号。 我错过了什么?

enter image description here

更新 表格中的数据日历的结构如下:

enter image description here

所以我修改了查询:

  DECLARE @CurrentMonth DATE = DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()), '19000101');
--print @CurrentMonth

SELECT 
    M_00 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 0 THEN 1 END),
    M_01 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 1 THEN 1 END),
    M_02 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 2 THEN 1 END),
    M_03 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 3 THEN 1 END),
    M_04 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 4 THEN 1 END),
    M_05 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 5 THEN 1 END),
    M_06 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 6 THEN 1 END),
    M_07 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 7 THEN 1 END),
    M_08 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 8 THEN 1 END),
    M_09 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 9 THEN 1 END),
    M_10 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 10 THEN 1 END),
    M_11 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 11 THEN 1 END)
FROM 
    dbo.tblCalendar c
        /* changed "YearNum, MonthNum"  instead of "(YEAR(c.dt), MONTH(c.dt)" */
    CROSS APPLY ( VALUES (DATEFROMPARTS(YearNum, MonthNum, 1)) ) fom (FirstOfMonth)
WHERE 
    /* changed c.MonthNum instead of c.dt */
    c.MonthNum >= MONTH(DATEADD(MONTH, -11, @CurrentMonth))
    /* changed c.MonthNum instead of c.dt */
    AND c.MonthNum < MONTH(DATEADD(MONTH, 1, @CurrentMonth));

这是对的吗?

对不起,我在这里感到困惑。这个想法是不是要使用动态的SQL? 只需使用我的查询,即:

;WITH cte_TopClasses
AS  ( 
SELECT
        c.YearNum,
        c.MonthNum,
        DD.ClassCode,
        ISNULL(SUM(prm.Premium),0) as NetWrittenPremium
FROM    tblCalendar c
LEFT JOIN  ProductionReportMetrics prm ON c.YearNum = YEAR(prm.EffectiveDate) and c.MonthNum = MONTH(prm.EffectiveDate) 
           AND CompanyGUID = '18E04C99-D796-4CFA-B1E7-28328321C8AD'      
LEFT JOIN [dbo].[Dynamic_Data_GLUnitedSpecialty] DD on prm.QuoteGUID = DD.QuoteGuid 
WHERE   ( c.YearNum = YEAR(GETDATE())-1 and c.MonthNum >= MONTH(GETDATE())+1 ) OR 
        ( c.YearNum = YEAR(GETDATE()) and c.MonthNum <= MONTH(GETDATE()) ) 
GROUP BY    c.YearNum,
            c.MonthNum,
            DD.ClassCode        
    ) 

select * from cte_TopClasses

输出:

enter image description here

2 个答案:

答案 0 :(得分:1)

我相信数据源中的表名必须是静态的,因为架构已保存。话虽如此,您可以根据当前月份的函数命名SSRS中的列。因此,您可以让数据集始终将列返回为11到0,并让SSRS将Tablix列动态命名为当前月减去列名。

答案 1 :(得分:1)

SSRS需要一组固定的输入列,这使得动态的piviot查询完全不兼容。将数据放入SSRS中,并让SSRS在矩阵上进行转移。

编辑...使用非动态sql ...

沿着这些方向做点什么......

DECLARE @CurrentMonth DATE = DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()), '19000101');

SELECT 
    M_00 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 0 THEN 1 END),
    M_01 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 1 THEN 1 END),
    M_02 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 2 THEN 1 END),
    M_03 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 3 THEN 1 END),
    M_04 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 4 THEN 1 END),
    M_05 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 5 THEN 1 END),
    M_06 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 6 THEN 1 END),
    M_07 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 7 THEN 1 END),
    M_08 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 8 THEN 1 END),
    M_09 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 9 THEN 1 END),
    M_10 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 10 THEN 1 END),
    M_11 = COUNT(CASE WHEN DATEDIFF(MONTH, fom.FirstOfMonth, @CurrentMonth) = 11 THEN 1 END)
FROM 
    dbo.Calendar c
    CROSS APPLY ( VALUES (DATEFROMPARTS(YEAR(c.dt), MONTH(c.dt), 1)) ) fom (FirstOfMonth)
WHERE 
    c.dt >= DATEADD(MONTH, -11, @CurrentMonth)
    AND c.dt < DATEADD(MONTH, 1, @CurrentMonth);

查询输出...

M_00        M_01        M_02        M_03        M_04        M_05        M_06        M_07        M_08        M_09        M_10        M_11
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
30          31          31          30          31          30          31          28          31          31          30          31

我们的想法是,列中的数据会将列作为月份进度循环,但列名称始终保持不变...因此它始终与SSRS一起使用。

然后,回到SSRS,而不是显示查询中的标题,使用公式表达式。像

这样的东西
=MonthName(month(Now()))
=MonthName(month(Now()) + 1)
=MonthName(month(Now()) + 2)
=MonthName(month(Now()) + 3)
...