我有几年前写的SSRS报告。我把它像一颗定时炸弹一样建造起来。我以为它会在2022年停止工作,我当时希望它会成为别人的问题,但我认为它会比我预测的更早停止工作,可能是在2018年或2019年。所以我觉得有点不得不尽可能修复它。我可以很容易地修改我在其生命周期中添加5或10年的内容,但我想知道我是否可以这样做,以便报告中的年份列数量根据年份范围参数传递的年数而变化。
该报告按年度称为合同资金,旨在报告合同在合同期内每年获得的资金。为了解决这个问题,我计算了合同生效的月数。然后我计算每月燃烧率是什么(资金/月)。然后我计算每个特定年份每个合约活跃多少个月。最后,对于每个指定年份的每个月,我使用燃烧率乘以活跃月份来计算每份合约每年收到的每笔资金。容易,对吗? :)
运行报告时,连同一堆过滤参数,用户必须选择的主要参数是要检查的年限。可能的年份始于1982年(当我们开业时)并持续到2022年(40年)。这就是问题所在;在我创造40年范围的方式。
RDL由存储过程提供支持。 SP声明了40年变量,表示报告可以返回的总年数。这些变量中的每一个都填充SP中的唯一列。在RDL中,有40列对应于每个SP列。
他们说一张图片胜过千言万语。希望如此!
这是RDL。 40年中的每一年都由一列代表。它们可以隐藏,也可以根据visibility属性显示。
所以,回顾一下,我的问题是我是否能够以不同的方式解决这个问题。业务需求是根据用户对年份日期范围的选择,生成可生成可变数量的年份输出列的报告。
先谢谢你的帮助!请询问是否需要澄清。
珍
更新:这是我目前的代码:
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中想要的是每一行代表合同资金记录与我检查的日期范围的交集,这样我就可以为每个合同资金记录操纵每年的资金,可以跨越多年。
答案 0 :(得分:2)
使用矩阵本来是一个更整洁的解决方案。这将允许您返回一个额外的字段来说明数据与哪一年相关,并自动创建所需的列数。如果任何年份没有数据,那么在基础查询中使用CROSS JOIN可能会填补空白。
在您尝试修补现有问题之前,我认为更多的研究可能对您有益
我希望以上帮助。请询问您是否需要更多信息。
<强>更新强>
为了响应上述问题中的所需输出,下面是使用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)
我希望这会有所帮助。询问您是否需要进一步的帮助