【问题标题】:Creating a varying number of column results in SSRS based on a range parameter根据范围参数在 SSRS 中创建不同数量的列结果
【发布时间】:2015-10-29 13:40:27
【问题描述】:

我有一份几年前写的 SSRS 报告。我把它建造得像个定时炸弹。我认为它会在 2022 年停止工作,我希望到那时它会成为其他人的问题,但我认为它会比我预期的更早停止工作,可能会在 2018 年或 2019 年。所以我觉得如果可能的话,我有义务修复它.我可以轻松地修改我必须将其寿命再延长 5 或 10 年的内容,但 我想知道我是否可以以不同的方式执行此操作,以便报告中的年份列数会根据使用 Year Range 参数传递的年份数

该报告称为“按年份的合同资金”,旨在报告合同在合同有效期内的每一年收到的资金金额。为了弄清楚这一点,我计算了合同有效的月份。然后我计算每月消耗率是多少(资金/月)。然后我计算每个特定年份每个合同的有效月数。最后,对于每个指定年份的每个月,我使用燃烧率乘以活跃月数来计算每个合同每年收到多少资金。容易,对吧? :)

在运行报告时,连同一堆过滤参数,用户必须选择的主要参数是要检查的年份范围。可能的年份从 1982 年(我们开业时)开始,一直持续到 2022 年(40 年)。这就是问题所在;以我创建 40 年范围的方式。

RDL 由存储过程提供支持。 SP 声明了 40 年变量,它们代表报告可以返回的总可能年数。这些变量中的每一个都填充 SP 中的唯一列。在 RDL 中,有 40 列对应于每个 SP 列。

他们说一张照片值一千字。但愿如此!

这是存储过程的一部分。您可以看到 40 年变量和 40 年列。

这是 SP 的结果。每一行都有 38 年的列是空的。

这里是 RDL。 40 年中的每一年都由一列表示。它们根据可见性属性隐藏或显示。

这是报告的结果。

所以,回顾一下,我的问题是我是否可以以不同的方式解决这个问题。业务需求是有一个可以根据用户选择的年份日期范围生成可变数量的年份输出列的报告。

提前感谢您的帮助!请问有什么需要澄清的。

詹妮弗


更新:这是我当前的代码:

declare @StartYear datetime  = '1/1/2009', @EndYear datetime = '12/31/2012'
Begin 
select 
cf.ContractFundingID, cf.StartDate, cf.EndDate
from ContractFunding cf 
where cf.StartDate <= @EndYear and cf.EndDate >= @StartYear
End
GO

我得到这样的结果:

ContractFundingID | StartDate | EndDate 
7363 | 2010-04-01 | 2011-02-28 
8767 | 2009-02-01 | 2011-12-31 
7466 | 2010-07-01 | 2011-06-30 
7503 | 2010-04-01 | 2011-03-31 

但我想要的是这样的:

ContractFundingID | StartDate | EndDate | Year 
7363 | 2010-04-01 | 2011-02-28 | 2009 
7363 | 2010-04-01 | 2011-02-28 | 2010 
7363 | 2010-04-01 | 2011-02-28 | 2011 
7363 | 2010-04-01 | 2011-02-28 | 2012 
8767 | 2009-02-01 | 2011-12-31 | 2009 
8767 | 2009-02-01 | 2011-12-31 | 2010 
8767 | 2009-02-01 | 2011-12-31 | 2011 
8767 | 2009-02-01 | 2011-12-31 | 2012 
7466 | 2010-07-01 | 2011-06-30 | 2009 
7466 | 2010-07-01 | 2011-06-30 | 2010 
7466 | 2010-07-01 | 2011-06-30 | 2011 
7466 | 2010-07-01 | 2011-06-30 | 2012 
7503 | 2010-04-01 | 2011-03-31 | 2009 
7503 | 2010-04-01 | 2011-03-31 | 2010 
7503 | 2010-04-01 | 2011-03-31 | 2011 
7503 | 2010-04-01 | 2011-03-31 | 2012 

我希望在 SQL 中的每一行都代表合同资金记录与我正在检查的日期范围的交集,以便我可以操纵每个合同资金记录的每年资金,该记录可以跨越多年.

【问题讨论】:

  • 提供代码,而不是图片。
  • 您唯一的问题是您是否可以采用不同的方式来处理这个问题?我怀疑你想要的不止这些。一个统计表会比所有那些硬编码的年份更好。而且标量函数调用看起来很痛苦。
  • Stanislovas,我很高兴发布代码,但不确定它有什么价值。这是一个很大的 SP,我并不是要求对代码进行必要的修复,而是要求如何从概念上改进此报告。我希望这是有道理的。谢谢!
  • @SeanLange 我不确定您是否建议与 Jonnus 类似的事情。如果是另一种方法,您能否指出正确的方向,以便我了解更多信息?
  • 我并不一定要提出太多建议。这主要是因为你完全不清楚你在问什么。

标签: sql-server reporting-services


【解决方案1】:

使用矩阵会是一个更整洁的解决方案。这将允许您返回一个额外的字段来说明数据与哪一年相关,并会自动创建所需的列数。如果任何年份都没有数据,那么在基础查询中使用 CROSS JOIN 可以填补空白。

我认为在您尝试修补现有问题之前进行更多研究可能对您有益

  • 查看here 了解矩阵的描述

  • CROSS JOINs 在这里解释

  • this 是另一个关于如何使用 CROSS JOINS 填补空白的 SO 问题

我希望以上帮助。请询问您是否需要更多信息。

更新

针对上述问题中所需的输出,这里是一个使用 CROSS JOIN 生成所需表的示例。

首先,您需要搜索日期之间的年份列表。使用常见的 tbale 表达式,您可以在此获取 @Start@End 日期之间的所有日期

DECLARE @Dates TABLE (YearNo INT)
;WITH n(n) AS
(
    SELECT YEAR(@Start)
    UNION ALL
    SELECT n+1 FROM n WHERE n < YEAR(@End)
)
INSERT INTO @Dates(YearNo)
SELECT n FROM n ORDER BY n

这将给出一个结果

YearNo
------
 1999
 2000
 (etc)

然后您可以使用前面提到的交叉连接,如下所示

SELECT v.ContractFundingID v.StartDate, v.EndDate, d.YearNo
FROM  @VALUES v
CROSS JOIN @Dates d

给出结果

ContractFundingID | StartDate  | EndDate    | YearNo
------------------+------------+------------+--------
7363              | 2010-04-01 | 2011-02-28 | 1999
8767              | 2009-02-01 | 2011-12-31 | 1999
7466              | 2010-07-01 | 2011-06-30 | 1999
7503              | 2010-04-01 | 2011-03-31 | 1999
7363              | 2010-04-01 | 2011-02-28 | 2000
(etc)

我希望这会有所帮助。询问您是否需要进一步的帮助

【讨论】:

  • 我绝对了解如何使用矩阵,并且我同意这将是一种更好的方法。事实上,我认为我在现有的 SQL SP 中完成的,实际上是一个强制矩阵。但要利用 SSRS 中的矩阵,我需要一个 SP,它为该范围内每一年的每个合同资金记录返回一行。我完全看到了在 RDL 中使用时它是如何工作的,并且我明白了为什么我需要使用 CROSS JOIN 来填补空白。我要去试一试。谢谢!
  • 没问题。试一试,如果你遇到困难,那么一定要在一个新问题上寻求更多帮助。正如上面评论中提到的,在共享代码时最好复制文本而不是图像。希望这在未来会更容易!
  • 我仍在努力解决我不理解的问题。我认为我的目标不是在我的 SQL 代码中创建矩阵,而是让 SSRS 处理它,对吗?如果是这样,那么我如何“返回一个额外的字段来说明数据与哪一年相关”?我在上面的问题中放了一些测试代码。
  • @JeniQ 关于您问题中的更新代码,您是在 2009 年、2010 年、2011 年、2012 年之后仅针对原始表中的每一行,还是您需要每一行的示例40 多年?
  • 简而言之,它是一种非常简洁的递归计算方式。您几乎总是可以使用 CTE 代替游标。我建议您阅读一下它们......也许这是一个很好的起点simple-talk.com/sql/t-sql-programming/sql-server-cte-basics
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-03
  • 2022-10-06
  • 2022-11-15
相关资源
最近更新 更多