微软BI 之SSRS 系列 - 基于时间段参数的 MDX 查询以及时间日历 Date Picker 的时间类型参数化
今天在天善问答里看到一个问题,如果我没有理解错的话,它应该是指比如在一个报表中选取一个时间段,然后求出这个时间段的某个 Measure 的 SUM 和。并且同时求出这两个时间点对应的上一年的时间点之间的同一个 Measure 的 SUM 和。
比如当前选取的时间点是 2004年1月8日,结束时间点是 2004年3月1日。那么不仅要求这个时间段的某度量值总和,并且还要求 2003年1月8日到2003年3月1日时间段的某度量值总和。 也就是说,这个时间段是一个动态的,根据输入的两个时间段决定当年和上一年的计算。
这个里面有几个小知识点,于是总结了一下,先看下面这个 Report 的效果。

还有使用 Date Picker 的效果 (注意如果使用日历控件,那么 StartDate 和 EndDate 的类型都是 Date/Time 类型)-

非 Date Picker 参数时的设计
在 Cube 中查一下验证一下,查询结果都是一样的。
WITH MEMBER [Measures].[Reseller Sales Amount of Period]
AS
SUM(
[Date].[Calendar].[Date].&[]:[Date].[Calendar].[Date].&[]
,[Measures].[Reseller Sales Amount]
)
MEMBER [Measures].[Reseller Sales Amount of Last Period]
AS
SUM(
[Date].[Calendar].[Date].&[]:[Date].[Calendar].[Date].&[]
,[Measures].[Reseller Sales Amount]
)
SELECT NON EMPTY{[Measures].[Reseller Sales Amount of Period],
[Measures].[Reseller Sales Amount of Last Period]} ON COLUMNS,
NON EMPTY { ([Product].[Category].[Category].ALLMEMBERS ) } ON ROWS
FROM [Step-by-Step]

新建一个 Dataset - Datedata,连接的是 MDX Step by Step 中的示例Cube。

MDX 查询语句取得时间成员和可以用在 Report 下拉框中的标签。
WITH MEMBER [Measures].[DateValue]
AS
[Date].[Calendar].CurrentMember.UniqueName
MEMBER [Measures].[DateLabel]
AS
[Date].[Calendar].CurrentMember.Name
SELECT
{ [Measures].[DateValue], [Measures].[DateLabel] } ON COLUMNS,
{ [Date].[Calendar].[Date]} ON ROWS
FROM [Step-by-Step]

创建两个时间参数 StartDate 和 EndDate 并且绑定到 DateData 中的时间成员,它们选择的都是 Text 类型,这一点一定要注意!!!。

新建一个 Dataset 用来展现表格上的数据,注意在 SSRS Report 中的参数使用一般都是通过这种类似于子查询的方式完成的。
WITH MEMBER [Measures].[Reseller Sales Amount of Last Year]
AS SUM(
{
-- 根据传入的参数分别取得上一年的开始时间点和结束时间点
PARALLELPERIOD([Date].[Calendar].[Calendar Year],
1,
STRTOMEMBER(@FromDateCalendar, CONSTRAINED)
):
PARALLELPERIOD([Date].[Calendar].[Calendar Year],
1,
STRTOMEMBER(@ToDateCalendar, CONSTRAINED)
)
},
[Measures].[Reseller Sales Amount]
)
SELECT NON EMPTY {[Measures].[Reseller Sales Amount],
[Measures].[Reseller Sales Amount of Last Year]} ON COLUMNS,
NON EMPTY { ([Product].[Category].[Category].ALLMEMBERS ) } ON ROWS
FROM (
-- Report 传入的开始参数和结束参数
SELECT ( STRTOMEMBER(@FromDateCalendar, CONSTRAINED) : STRTOMEMBER(@ToDateCalendar, CONSTRAINED) )
ON COLUMNS
FROM [Step-by-Step]
)

保存并在 Dataset 中绑定两个时间参数。

这样基本上就完成了基于时间区间的同比时间段的报表。

还有一点要注意一下,比如像这个查询是不会返回结果的,因为2004年的上一年不是闰年。

但是是有2003年2月28日这一天的,尽管下面的查询返回一个 NULL 但是这个成员是存在的。

Date Picker 时的设计

在文章一开始的时候就介绍了,如果把时间参数设计成日历形式那么就需要将参数的类型从 Text 类型改成 Date/Time 类型。

并且这里没有指定可供选择的值,因为一旦指定了值日历控件的样式就又会变成下拉框的样式。

同时在 DateSet 那里要改变参数的格式,因为 Date\Time 类型是时间类型,并不是字符串类型,因此需要将它们转变成字符串格式。

转变的格式代码如下:
="[Date].[Calendar].[Date].&["& Format(CDate(Parameters!StartDate.Value),"yyyyMMdd") + "]"

你可以从网上搜索到很多种不同的别人告诉你如何转换格式的经验和代码,但是要注意,你首先要确定的是你要转换的对象是什么?它需要什么格式?
先最好能够通过下面这种最简单的代码查看一下这种 Hard Code 形式的参数行不行,没有问题之后再放到上面去编辑。
在网上搜索到的转换过程一般都是使用作者自己代码示例的层次结构,比如说有的就是[Date].[Calendar].&[20040228], 少了一个 Level。
第二就是转换的字符串格式可能并不是 yyyyMMdd 的类型,而是 yyyy-MM-dd 的类型,所以这两点一定要注意。注意到了,你的转换才会成功!

最后一个问题,就是如果用户选择了一个非法的成员传入的时候就会出现这个错误,原因是我们的成员并不包含 11/1/2013 或者 11/29/2013。所以实际上还是使用下拉框的形式最直接,最简单,因为它可直接限定可选择的内容,可以做成年月日级联的效果。

总结:
- 在 SSRS Report 中使用下拉框等具有值和标签特征的组件时,可以参照本文的方式来绑定。
- 有关 SSRS Report 传递 MDX 查询参数的相关文章还可以参看 SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表。
- 有关 MDX 时间函数 PARALLELPERIOD 可以参看这篇文章 MDX Step by Step 读书笔记(九) - Working with Time 处理时间。
- STRTOMEMBER 函数的使用也需要注意一下,还有其它比较类似的例如 STRTOSET 等等都是可以将字符串转成对象或者集合。
更多 BI 文章请参看 BI 系列随笔列表 (SSIS, SSRS, SSAS, MDX, SQL Server)
如果觉得这篇文章看了对您有帮助,请帮助推荐,以方便他人在 BIWORK 博客推荐栏中快速看到这些文章。
微软BI 之SSRS 系列 - 基于时间段参数的 MDX 查询以及时间日历 Date Picker 的时间类型参数化的更多相关文章
- 微软BI 之SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表
基于数据仓库上的 SSRS 报表展示,一般可以直接通过 SQL 查询,存储过程,视图或者表等多种方式将数据加载并呈现在报表中.但是如果是基于 Cube 多维数据集的数据查询,就不能再使用 SQL 的语 ...
- 微软BI 之SSRS 系列 - 在 Cube 中通过 MDX 查询实现基于父子递归关系的汇总报表
之前我写了一篇在 SSRS 开发中处理这种父子关系的汇总与聚合的文章 (SSRS 系列 - 使用分组 Group 属性实现基于父子递归关系的汇总报表),示例中的查询是基于 SQL Server 关系型 ...
- SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表
SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表 SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表 2013-10-09 23:09 by BI Wor ...
- 微软BI 之SSRS 系列 - 使用分组 Group 属性实现基于父子递归关系的汇总报表
基于父子关系的递归结构在公司组织结构里比较常见,基本上都是在一张表里实现的自引用关系.在报表中如果要实现这种效果,并且在这个基础上做一些数据的汇总,可以使用到下面提到的方法. 要实现的效果大致如下 - ...
- 微软BI 之SSRS 系列 - 如何在 MDX 查询中获取有效的 MEMBER 成员属性作为参数传递
这篇小文章的来源是 天善问答,比如在报表中要根据点击某一个成员名称然后作为参数传递给自身报表或者下一张报表,这个在普通的 SQL 查询中没有任何问题.但是在 MDX 中查询是有区别的,比如在 MDX ...
- 微软BI 之SSRS 系列 - 如何实现报表导航 Navigation 和钻取 Drill Down 的效果
开篇介绍 如何在 SSRS 报表中实现标签导航 Navigation 和向下钻取 Drill Down的效果? 如同下面这个例子一样 - 在页面第一次加载的时候,默认显示是全部地区的销售总和情况,上面 ...
- 微软BI 之SSRS 系列 - 使用 LookupSet 和 Adjacent Group 等高级技巧在报表中跨 Dataset 分组查询
SSRS 报表中有一些高级的技巧,平常很少用到,下面我通过这个案例来展现一下如何在实际开发中使用它们,并且如何解决一些实际的需求. 这张报表分别统计了不同的 Product 产品在不同的月份的 Ord ...
- 微软BI 之SSRS 系列 - 实现 Excel 中图表结合的报表设计
来自群里面讨论的一个问题,EXCEL 中有类似于这样的图形,上面是 Chart, Chart X轴上的值正好就是下方 Table 的列头,这个在 SSRS 中应该如何实现? SSRS 2008.2 ...
- 微软BI 之SSRS 系列 - 报表邮件订阅中 SMTP 服务器匿名访问与 Windows验证, 以及如何成功订阅报表的实例
这篇文章源于在上一篇博文中有园友提出订阅 SSRS 报表时的一个问题, 于是就好好总结了一下,把有关 SSRS 报表订阅的要点和容易出现问题的地方写出来,希望对大家有所帮助! 参看上一篇博文 - S ...
随机推荐
- cf220b
不知道为什么线段树区间更新专题里有这题.. 可以用莫队解,也可以直接开数组解 /* n个询问,m个元素 O(m*m):记录每个元素出现次数,筛掉出现次数小于数值的数 */ #include<io ...
- poj3237树链剖分边权+区间取负
树链剖分+线段树lazy-tag在树链上操作时千万不要写错.. /* 树链剖分+线段树区间变负 */ #include<iostream> #include<cstring> ...
- splay好板子
找到一份比较好的板子,链接https://blog.csdn.net/crazy_ac/article/details/8034190 #include<cstdio> #include& ...
- 使用@property - 廖雪峰的官方网站
使用@property 阅读: 20616 在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 9 ...
- pytest一:pytest 框架介绍
pytest 是 python 的一种单元测试框架,与python 自带的 unittest测试框架类似,但是比 unittest 框架使用起来更简洁,效率更高.根据pytest 的官方网站介绍,它具 ...
- JavaScript常见的假值
值 说明 var a=false; 值等于false(假) var a =0; 值等于0 var a=''; 空的字符串 var a=10/'abc' NaN var a; 未赋值变量
- ERP采购申请管理(三十九)
获取当前表单在流程中的状态: /// <summary> /// 获取当前表单在流程表中的状态 /// </summary> /// <param name=" ...
- 在Centos下用alternative命令切换各个版本的jdk的方法
https://blog.csdn.net/nsrainbow/article/details/43273991 https://blog.csdn.net/yzh_1346983557/articl ...
- [转] Java接口_interface_implements
相对抽象类来讲,接口就是比抽象类还要抽象的抽象类,丝毫不带半点实现的内容.接口可以更加规范的对子类进行约束.接口全面地专业地实现了:规范和具体实现的分离.接口就是规范,定义的是一组规则,提现了现实世界 ...
- Android Studio之导出JavaDoc出现编码GBK的不可映射字符
使用Android Studio导出JavaDoc时,如果在注释中添加了中文,生成时的时候会出现错误: 编码GBK的不可映射字符. 解决的办法是在Other command line argument ...