微软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 ...
 
随机推荐
- python接口自动化测试二:常用操作
			
url = '接口地址' r = requests.get(url) # 发送get请求 print(r.status_code) ...
 - git提交本地分支到远程分支
			
git提交本地分支到远程分支 git 常用命令(含删除文件) Git常用操作命令收集: 1) 远程仓库相关命令 检出仓库:$ git clone git://github.com/jquery/j ...
 - 02_kettle插件开发
			
先下载标准插件模板 地址 http://www.ahuoo.com/download/TemplateStepPlugin.rar 将下载的jar包解压后 导入eclipse项目中 有 ...
 - bzoj3687
			
3687: 简单题 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 700 Solved: 319[Submit][Status][Discuss] ...
 - 【Java】 剑指offer(67) 把字符串转换成整数
			
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 请你写一个函数StrToInt,实现把字符串转换成整数这个功能 ...
 - HDU1211 密文解锁 【扩展欧几里得】【逆元】
			
<题目链接> <转载于 >>> > 题目大意: RSA是个很强大的加密数据的工具,对RSA系统的描述如下: 选择两个大素数p.q,计算n = p * q,F( ...
 - hdu1698 Just a Hook 【区间修改】(模板题)
			
题目链接:https://vjudge.net/contest/182746#problem/E 题目大意: 一段线段由n条小线段组成,每次操作把一个区间的小线段变成金银铜之一(金的价值为3,银为2, ...
 - 第一次亲密接触MSF
			
第一次亲密接触MSF Metasploit Framework介绍 Metasploit是一款开源安全漏洞检测工具,附带数百个已知的软件漏洞,并保持频繁更新.被安全社区冠以“可以黑掉整个宇宙”之名的强 ...
 - epoll使用详解
			
目录 epoll介绍 Epoll的优点: 1.支持一个进程打开大数目的socket描述符(FD) 2.IO效率不随FD数目增加而线性下降 3.支持边缘触发模式 4.使用mmap加速内核与用户空间的消息 ...
 - 洛谷.2292.[HNOI2004]L语言(Trie DP)
			
题目链接 /* 简单的DP,查找是否有字典中的单词时在Trie树上做 要注意在最初Match(0)一遍后,i还是要从0开始匹配,因为如果有长度为1的单词,Match(i+1)不会从1更新 1M=102 ...