微软BI 之SSRS 系列 - 使用 LookupSet 和 Adjacent Group 等高级技巧在报表中跨 Dataset 分组查询
SSRS 报表中有一些高级的技巧,平常很少用到,下面我通过这个案例来展现一下如何在实际开发中使用它们,并且如何解决一些实际的需求。
这张报表分别统计了不同的 Product 产品在不同的月份的 Order 订单数量, Due 付款数量和 Ship 装船数量。
Start Date 和 End Date 的时间范围作为筛选,很显然第一个 Matrix 是以 Order Date 作为比较条件,第二个是以 Due Date, 第三是以 Ship Date 作为比较条件。
现在需要变成这样的一种需求 - 在一个 Matrix 中来展现按月分组之后的 Order Count, Due Count, Ship Count。
这个变化复杂在什么地方?
第一 ,无法确定到底是按照 Order Date, Due Date 还是 Ship Date 作为列的父分组,如果按照 Order Date 分组,那么 Due Count 和 Ship Count 下的数据又该如何统计。很显然订单日期在 2007年7月份的这笔订单,它的 Due Date 有可能落在 2007年8月份,它的 Ship Date 有可能落在 2007年9月。但是在一个 Dataset 中只能要么按照 Order Date,要么按照 Due Date 或者 Ship Date 来过滤。因此既不能按照 Order Date,也不能按照 Due Date 或者 Ship Date 来作为查询的 WHERE 条件。
第二,在月份的分组之下没有条件能够判断那些数据是属于 Order Count, Due Count 和 Ship Count。月份之下的分组没有依据,无法分组。
当然解决以上两个问题在 SQL 查询中是比较容易解决的,就是通过硬编码将三个查询出来的 Dataset 合并成一个更大的 Dataset 并设置列标识。
但是现在的问题是,这三个 Dataset 已经都存在了,并且我们假设是没有办法改变的情况下如何解决这个问题,比如数据源使用的是无法通过 SQL 查询的 Report Model 的 Entity。
三个 Dataset 的示例查询语句,可以自行替换日期参数。
USE AdventureWorksDW2008R2
GO SELECT DP.EnglishProductName,
F.SalesOrderNumber,
DD.FullDateAlternateKey AS 'OrderDate'FROM dbo.FactInternetSales AS F
INNER JOIN dbo.DimProduct AS DP
ON F.ProductKey = DP.ProductKey
INNER JOIN dbo.DimDate AS DD
ON F.OrderDateKey = DD.DateKey
WHERE DD.FullDateAlternateKey BETWEEN '2007-01-01' AND '2007-09-30'AND DP.EnglishProductName IN ('Adjustable Race',
'All-Purpose Bike Stand',
'AWC Logo Cap',
'BB Ball Bearing',
'Bearing Ball') SELECT DP.EnglishProductName,
F.SalesOrderNumber,
DD.FullDateAlternateKey AS 'DueDate'FROM dbo.FactInternetSales AS F
INNER JOIN dbo.DimProduct AS DP
ON F.ProductKey = DP.ProductKey
INNER JOIN dbo.DimDate AS DD
ON F.DueDateKey = DD.DateKey
WHERE DD.FullDateAlternateKey BETWEEN '2007-01-01' AND '2007-09-30'AND DP.EnglishProductName IN ('Adjustable Race',
'All-Purpose Bike Stand',
'AWC Logo Cap',
'BB Ball Bearing',
'Bearing Ball') SELECT DP.EnglishProductName,
F.SalesOrderNumber,
DD.FullDateAlternateKey AS 'ShipDate'FROM dbo.FactInternetSales AS F
INNER JOIN dbo.DimProduct AS DP
ON F.ProductKey = DP.ProductKey
INNER JOIN dbo.DimDate AS DD
ON F.ShipDateKey = DD.DateKey
WHERE DD.FullDateAlternateKey BETWEEN '2007-01-01' AND '2007-09-30'AND DP.EnglishProductName IN ('Adjustable Race',
'All-Purpose Bike Stand',
'AWC Logo Cap',
'BB Ball Bearing',
'Bearing Ball')
新建一个报表,并拖放一个 Matrix,并预先只选择包含有订单的 Dataset,行以 English Product Name 来分组,列暂时不动。
在 Column Group 右键选择添加一个分组,暂时按照 OrderDate 分组,不要选择 ‘Add Group header’。
这样一来 ColumnGroup 之上就有一个 OrderDate 的分组了,继续选择 ColumnGroup 并选择添加 Adjacent After。
Adjacent Group - 相邻的分组,这样在 OrderDate 父分类下就可以创建一个或者多个并列的子分组了。
ColumnGroup 是以 Order Date 作为分组的依据的,这里为它添加两个同样以 Order Date 分组的相邻分组。
要注意这个分组的括号的变化,与直接在子分组下邮件添加新列是有区别的。
将所有按照 OrderDate 分组的条件格式化,因为 Order Date 本身是类似于年-月-日结构的,但是我们分组的条件是基于年-月级别。
只有按照这种分组方式,才可以将第二个相邻分组和第三个相邻分组的列名更改掉。
因为上面分组的条件是按照 yyyy-MM 格式化的,为了后面条件对比的统一性,为每一个 Dataset 添加一个 KEY,也按照这个格式格式化。
添加了 OrderMonthKey, DueMonthKey 和 ShipMonthKey。
在第二个相邻和第三个相邻分组的聚合数据处要实现这样的逻辑:
由于父分组都是按照 Order Date 来分组的,并且所有三个子分组也都是按照 Order Date 来分组的,所以如果按照第一个子分组下的 Count(SalesOrderNumber) 复制到第二个或者第三个子分组的话,结果应该是一样的。
这样就先解决了第一个分组的问题。
第二就是继续以 OrderDate 作为查找条件,去查找有哪些 Due Date 和 Ship Date 在同一个月的 SalesOrderLineNumber。
因此在第二个子分组中,计算在这个月中的 Due Count 就是如下逻辑 -
通过当前 Order Month,到 DS_DUE Dataset 中去比较有哪些 Due Month 和 Order Month 是一样的,于是把查询到的 SalesOrderNumber 全部返回回来。最后通过 .Length 来获取返回的 SalesOrderNumber 数量。
这个逻辑也用到 Ship 分组统计上。
再来比较一下之前的报表
和更改之后的报表 - 修改之后的报表出现了问题。所有产品的 Due Count 和 Ship Count 都是一样的,结果不正确。
错误的原因是什么 ? 因为在 Lookup 查找的时候没有考虑行分组的问题,也就是说 Lookup 的时候只考虑了比较月份,而没有考虑要同时比较产品和月份,即不同的产品下,不同月份下的 Sales Order Count。
引申了一个新的技巧 - 如何在 LookupSet 的时候比较多个列 ? 其实很简单,拼接字符串即可。
保存并查看报表,这次就都正确了。
上面的这些报表处理技巧在实际开发过程中非常实用,可以在不更改原有 Dataset 和查询结构的情况下很容易的实现了新的需求。
关于 LookupSet 的使用可以参考 MSDN LookupSet,同时 Lookup 函数也是非常常用的,不同的是 Lookup 是返回一对一的结果,而 LookupSet 是一对多的结果。
更多 BI 文章请参看 BI 系列随笔列表 (SSIS, SSRS, SSAS, MDX, SQL Server)
如果觉得这篇文章看了对您有帮助,请帮助推荐,以方便他人在 BIWORK 博客推荐栏中快速看到这些文章。
微软BI 之SSRS 系列 - 使用 LookupSet 和 Adjacent Group 等高级技巧在报表中跨 Dataset 分组查询的更多相关文章
- 微软BI 之SSRS 系列 - 基于时间段参数的 MDX 查询以及时间日历 Date Picker 的时间类型参数化
今天在天善问答里看到一个问题,如果我没有理解错的话,它应该是指比如在一个报表中选取一个时间段,然后求出这个时间段的某个 Measure 的 SUM 和.并且同时求出这两个时间点对应的上一年的时间点之间 ...
- 微软BI 之SSRS 系列 - 使用带参数的 MDX 查询实现一个分组聚合功能的报表
基于数据仓库上的 SSRS 报表展示,一般可以直接通过 SQL 查询,存储过程,视图或者表等多种方式将数据加载并呈现在报表中.但是如果是基于 Cube 多维数据集的数据查询,就不能再使用 SQL 的语 ...
- 微软BI 之SSRS 系列 - 在 Cube 中通过 MDX 查询实现基于父子递归关系的汇总报表
之前我写了一篇在 SSRS 开发中处理这种父子关系的汇总与聚合的文章 (SSRS 系列 - 使用分组 Group 属性实现基于父子递归关系的汇总报表),示例中的查询是基于 SQL Server 关系型 ...
- 微软BI 之SSRS 系列 - 实现 Excel 中图表结合的报表设计
来自群里面讨论的一个问题,EXCEL 中有类似于这样的图形,上面是 Chart, Chart X轴上的值正好就是下方 Table 的列头,这个在 SSRS 中应该如何实现? SSRS 2008.2 ...
- 微软BI 之SSRS 系列 - 报表邮件订阅中 SMTP 服务器匿名访问与 Windows验证, 以及如何成功订阅报表的实例
这篇文章源于在上一篇博文中有园友提出订阅 SSRS 报表时的一个问题, 于是就好好总结了一下,把有关 SSRS 报表订阅的要点和容易出现问题的地方写出来,希望对大家有所帮助! 参看上一篇博文 - S ...
- 微软BI 之SSRS 系列 - 如何实现报表导航 Navigation 和钻取 Drill Down 的效果
开篇介绍 如何在 SSRS 报表中实现标签导航 Navigation 和向下钻取 Drill Down的效果? 如同下面这个例子一样 - 在页面第一次加载的时候,默认显示是全部地区的销售总和情况,上面 ...
- 微软BI 之SSRS 系列 - 巧用 RunningValue 函数在分组中排序并设置 RANK 排名
开篇介绍 经常有像类似于这样的排序需求,以及设置分组下的排序序号.比如此图中要求城市 City 在省份下按照 Internet Sales Amount 总销售额进行排序,并标识在各省份下的排名. 实 ...
- 微软BI 之SSRS 系列 - 如何设置页标题重复
开篇介绍 这个问题大家经常碰到,特意写一下如何解决这个小问题. 问题 默认情况下当报表超过一定的高度会自动分成多页. 第二页默认是看不到标题的. 解决方法 2012版本下在 Column Groups ...
- 微软BI 之SSRS 系列 - 如何在 MDX 查询中获取有效的 MEMBER 成员属性作为参数传递
这篇小文章的来源是 天善问答,比如在报表中要根据点击某一个成员名称然后作为参数传递给自身报表或者下一张报表,这个在普通的 SQL 查询中没有任何问题.但是在 MDX 中查询是有区别的,比如在 MDX ...
随机推荐
- require.js 简洁入门
原文地址:http://blog.sae.sina.com.cn/archives/4382 前言 提到require.js大多数人会说提到模块化开发,AMD等等,其实require.js并没有这么多 ...
- android中Bitmap的放大和缩小的方法
android中Bitmap的放大和缩小的方法 时间 2013-06-20 19:02:34 CSDN博客原文 http://blog.csdn.net/ada168855/article/det ...
- WordPress主题开发:开启侧边栏小工具功能
步骤一:在主题的functions.php中,添加一段代码,开启侧边栏功能,代码如下: <?php //参数 $args = array( 'name' => __( '主侧边栏'), ' ...
- Spring Boot新模块devtools
Spring Boot 1.3中引入了一个新的模块,devtools. 顾名思义,这个模块是为开发者构建的,目的在于加快开发速度. 这个模块包含在最新释出的1.3.M1中. 自动禁用模板缓存 一般情况 ...
- Build Web Apps in Node and Express视频下载
上传到百度云了,点击这里下载>> 作者使用的是Mac系统,不过Windows也差不多,主要理解express一些基本配置和使用,讲的比较基础,希望对node.js.express有兴 ...
- zoj2334 Monkey King , 并查集,可并堆,左偏树
提交地址:点击打开链接 题意: N(N<=10^5)仅仅猴子,初始每仅仅猴子为自己猴群的猴王.每仅仅猴子有一个初始的力量值.这些猴子会有M次会面. 每次两仅仅猴子x,y会面,若x,y属于同一个 ...
- Newtonsoft.Json高级用法,json序列号,model反序列化,支持序列化和反序列化DataTable,DataSet,Entity Framework和Entity,字符串
原文地址:https://www.cnblogs.com/yanweidie/p/4605212.html 手机端应用讲究速度快,体验好.刚好手头上的一个项目服务端接口有性能问题,需要进行优化.在接口 ...
- ASP.NET MVC:WebViewPage.cs
ylbtech-funcation-Utility: ASP.NET MVC:WebViewPage.cs 表示呈现使用 ASP.NET Razor 语法的视图所需的属性和方法. 1.A,WebVie ...
- Java系列:JVM中的OopMap(zz)
调用栈里的引用类型数据是GC的根集合(root set)的重要组成部分:找出栈上的引用是GC的根枚举(root enumeration)中不可或缺的一环. JVM选择用什么方式会影响到GC的实现: 如 ...
- Visio中方向键不能移动物件而是滚动画布
不知怎么的, 我的Visio中按方向键不能移动目标对象, 效果却是移动整个画布. 上网查了一下, 找到了原因. 因为不知怎么的错按了键盘上的Scroll Lock键, 再按一下就好了. 参考资 ...