命名集是SSAS中非常有用的一个元素,和Calculated Members(计算成员)一样能够简化我们的很多工作并且之间还有些许的联系。那么什么是Named Sets呢,简单的说就是分配了名字的成员和元组集。我们通过定义Named Sets来使得用户更方便的构建自己的查询,并帮助开发人员编写具有高可读性的代码。
Regular Named Sets
让我们通过例子来看看如何使用Named Sets。我么的用户想要建立一个Excel报表用来显示当前月、前一月的销售额以及最近三年的销售总额。如果不使用Named set,用户需要在每个月月初来更新报表中选定的日期以便显示最近月份的数据。为了避免这么做,我们可以定义一个包含用户想在报表中看到的日期范围的Named Set,用户也不需要再次手动更新。以下介绍了如何做到这些:
首先,我们需要确定哪些月份是有销售数据的,因为在日期维度中包含的将来日期肯定不包含任何销售数据。这个可以通过NonEmpty函数计算:
CREATE HIDDEN SET CurrentCube.[ExistingSalePeriods] AS NonEmpty ( [Date].[Calendar].[Month].Members, Measures.[Sales Amount] ); |
我们将这个命名集设置为对用户隐藏,因为它只会在中间步骤被使用而无需呈现给用户。
接下来,我们将创建一个前一月的日期命名集。因为我们仍然对前一月的销售数据感兴趣,而且我们已经定义了截至目前为止的所有有销售数据的日期集,所以我们可以很容易的得到前一月的定义:
CREATE SET CurrentCube.[LastSaleMonth] AS Tail (ExistingSalePeriods, 1); |
有了前一月的定义,我们离目标又近了一步。当然,它对于用户来说也是有用的,所以我们设置为对用户可见。最后一个命名集定义是包含年这一层次的成员集合。下边我们创建一个包含最近一年销售数据的命名集:
CREATE SET CurrentCube.[LastSaleYear] AS Ancestor ( LastSaleMonth.Item (0), [Date].[Calendar].[Calendar Year] ); |
最后一步是创建我们最终的命名集:
CREATE SET CURRENTCUBE.LastSaleAnalysisPeriod AS { LastSaleYear.Item (0).Lag(2) : LastSaleYear.Item (0), LastSaleMonth.Item (0).PrevMember, LastSaleMonth.Item (0) } ; |
现在,命名集已经成功创建,用户可以很容易地通过客户端工具在报表中使用:
命名集在每次对Cube的处理时进行创建和计算,这样,每个新的月份的销售数据显示,命名集都会反应今年以及报表显示所需要的时间并刷新报表数据。
动态命名集(Dynamic Named Set)
创建命名集的时候允许你选择是静态(Static)还是动态(Dynamic)命名集,对于静态命名集(Static),数据将被保留一直到对Cube执行下一次的处理。只某些情况下静态的是有用的,比如你想提高查询性能,但有时却相当令人沮丧,比如我们要定义一个集合包含10个最畅销的产品:
CREATE SET CURRENTCUBE.Best10Products AS TopCount ( Product.Product.Product.Members, 10, Measures.[Sales Amount] ); |
由于静态命名集只计算一次,Best10Products 命名集将包含所有可以在所有时间中最畅销的产品。换句话说,当命名集被计算时,它不知道在哪个查询中会被使用到。然而,这个命名集不会在报表中被用到太多,因为在报表中很可能是对每个国家每一月销售量的前十位进行统计,这样静态命名集就没法实现。例如,以下两个查询将一直返回相同的产品列表即便它们选定的年份不同:
SELECT Measures.[Sales Amount] ON COLUMNS, Best10Products ON ROWS FROM [Adventure Works] WHERE ([Date].[Calendar].[Calendar Year].&[2001])
SELECT Measures.[Sales Amount] ON COLUMNS, Best10Products ON ROWS FROM [Adventure Works] WHERE ([Date].[Calendar].[Calendar Year].&[2004]) |
Analysis Services 2008引入了动态命名集(Dynamic)来解决这个问题。动态命名集会在Where子句的上下文中总是被重新计算,也就是说动态命名集在每个查询中都被重新计算一次。
CREATE DYNAMIC SET CURRENTCUBE.[Best10ProductsDynamic] AS TopCount ( Product.Product.Product.Members, 10, Measures.[Sales Amount] ); |
现在我们再次运行以下两个查询:
SELECT Measures.[Sales Amount] ON COLUMNS, Best10ProductsDynamic ON ROWS FROM [Adventure Works] WHERE ([Date].[Calendar].[Calendar Year].&[2001])
SELECT Measures.[Sales Amount] ON COLUMNS, Best10ProductsDynamic ON ROWS FROM [Adventure Works] WHERE ([Date].[Calendar].[Calendar Year].&[2004]) |
现在我们得到了正确的每一年中最畅销的10个产品列表。