Power Pivot 中的日期表对于浏览和计算一段时间内的数据非常重要。 本文全面介绍日期表以及如何在 Power Pivot 中创建日期表。 本文特别介绍:
- 为什么日期表对于按日期和时间浏览和计算数据很重要。
- 如何使用 Power Pivot 将日期表添加到数据模型。
- 如何在日期表中新建日期列,如年、月和期间。
- 如何在日期表和事实表之间创建关系。
- 如何利用时间。
本文面向不熟悉 PowerPivot 的用户。 但是,重要的是已经充分了解导入数据、创建关系以及创建计算列和度量。
本文 不 介绍如何在度量值公式中使用 DAX Time-Intelligence 函数。 有关如何使用 DAX 时间智能函数创建度量值的详细信息,请参阅 Excel 中 Power Pivot 中的时间智能。
注意
在 Power Pivot 中,“度量值”和“计算字段”这两个名称是同义词。 在本文中,我们将使用名称度量值。 有关详细信息,请参阅 Power Pivot 中的度量值。
目录
了解日期表
几乎所有数据分析都涉及浏览和比较日期和时间的数据。 例如,您可能希望对上一个会计季度的销售金额进行求和,然后将这些总计与其他季度进行比较,或者您可能希望计算帐户的月末期末余额。 在每种情况下,您都使用日期作为对特定时间段内的销售交易或余额进行分组和汇总的一种方式。
Power View 报表
日期表可以包含日期和时间的许多不同表示形式。 例如,日期表通常包含“会计年度”、“月”、“季度”或“期间”等列,在对数据透视表或 Power View 报表中的数据进行切片和筛选时,可以从字段列表中选择这些列作为字段。
Power View 字段列表
要使日期列(如年、月和季度)包括各自范围内的所有日期,日期表 必须 至少具有一列和一组连续的日期。 也就是说,该列必须具有日期表中包含的每一年的每一天一行。
例如,如果要浏览的数据的日期为 2010 年 2 月 1 日到 2012 年 11 月 30 日,并且您报告的日历年,则您需要一个日期表的日期范围至少为 2010 年 1 月 1 日到 2012 年 12 月 31 日。 日期表中的每一年都必须包含每年的所有天数。 如果您要定期使用较新的数据刷新数据,您可能希望将结束日期提前一两年,这样您就不必随着时间的流逝而更新日期表。
具有一组连续日期的日期表
如果您报告某个会计年度,则可以创建一个日期表,其中包含每个会计年度的一组连续日期。 例如,如果您的会计年度从 3 月 1 日开始,并且您有 2010 财年到当前日期的数据 (例如,在 2013 财年) ,您可以创建一个从 2009 年 3 月 1 日开始并且至少包括每个会计年度中到 2013 财年最后一天的每一天的日期表。
如果您将同时报告日历年和会计年度,则无需创建单独的日期表。 单个日期表可以包含日历年、会计年度甚至 13 个四周期间日历的列。 重要的是您的日期表包含所有年份的一组连续日期。
将日期表添加到数据模型
有几种方法可以将日期表添加到数据模型:
- 从关系数据库或其他数据源导入。
- 在 Excel 中创建日期表,然后在 Power Pivot 中复制或链接到新表。
- 从 Microsoft Azure 市场导入。
如果您从数据仓库或其他类型的关系数据库导入部分或全部数据,则很可能已经存在日期表以及它与您要导入的其余数据之间的关系。 日期和格式可能会与事实数据中的日期相匹配,并且日期可能从过去开始并追溯到遥远的未来。 您要导入的日期表可能非常大,并且包含的日期范围超出了数据模型中需要包含的日期范围。 可以使用 PowerPivot 的表导入向导的高级筛选器功能有选择地仅选择日期和你真正需要的特定列。 这可以显著减小工作簿的大小并提高性能。
表导入向导
在大多数情况下,无需创建任何其他列,如“会计年度”、“周”、“月名”等,因为它们已存在于导入的表中。 但是,在某些情况下,将日期表导入数据模型后,您可能需要创建其他日期列,具体取决于特定的报告需求。 幸运的是,使用 DAX 很容易做到这一点。 稍后将了解有关创建日期表字段的详细信息。 每个环境都是不同的。 如果您不确定您的数据源是否具有相关的日期或日历表,请联系您的数据库管理员。
在 Excel 中创建日期表
可以在 Excel 中创建日期表,然后将其复制到数据模型中的新表中。 这真的很容易做到,它给了你很大的灵活性。
在 Excel 中创建日期表时,必须从包含连续日期范围的单个列开始。 然后,你可以使用 Excel 公式在 Excel 工作表中创建其他列,如年、季度、月、会计年度、期间等,或者,在将表复制到数据模型后,也可以将它们创建为计算列。 本文后面的“向 日期表添加新日期列 ”部分介绍如何在 Power Pivot 中创建其他日期列。
如何:在 Excel 中创建日期表并将其复制到数据模型中
在 Excel 的空白工作表单元格 A1 中,键入列标题名称以标识日期范围。 通常,这类似于 Date、DateTime 或 DateKey。
在单元格 A2 中,键入开始日期。 例如, 2010 年 1 月 1 日。
单击填充柄并将其向下拖动到包含结束日期的行号。 例如, 12/31/2016。
选择“ 日期 ”列中的所有行, (包括单元格 A1) 中的标题名称。
在“ 样式 ”组中,单击 “套用表格格式”,然后选择样式。
在“ 套用表格格式” 对话框中,单击“ 确定”。
复制所有行,包括标题。
在 Power Pivot 的 “开始 ”选项卡上,单击 “粘贴”。
在“粘贴预览>表名称”中,键入日期或Calendar等名称。 选中“ 将第一行用作列标题”,然后单击“ 确定”。
Power Pivot 中名为 Calendar 的新日期表 () 如下所示:
注意
还可以使用“ 添加到数据模型”创建链接表。 但是,这会使工作簿变得不必要地大,因为工作簿具有两个版本的日期表;一个在 Excel 中,一个在 Power Pivot 中。
注意
名称日期是 Power Pivot 中的关键字 (keyword) 。 如果将在 Power Pivot 中创建的表命名为“日期”,则需要在参数中引用表名称的任何 DAX 公式中使用单引号将表名括起来。 本文中的所有示例图像和公式均引用在 Power Pivot 中创建的名为 Calendar 的日期表。
现在,数据模型中有了一个日期表。 可以使用 DAX 添加新的日期列,如年、月等。
向日期表添加新的日期列
具有单个日期列且每年的每一天都有一行的日期表对于定义日期范围内的所有日期非常重要。 在事实数据表和日期表之间创建关系也是必需的。 但是,在数据透视表或 Power View 报表中按日期进行分析时,每天有一行的单个日期列没有用处。 你希望日期表包含有助于汇总某个日期范围或一组日期的数据的列。 例如,你可能希望按月或按季度对销售额进行求和,也可以创建一个计算同比增长的度量。 在每种情况下,日期表都需要年、月或季度列,以便聚合该期间的数据。
如果从关系数据源导入日期表,则它可能已包含所需的不同类型的日期列。 在某些情况下,您可能希望修改其中的某些列或创建其他日期列。 如果在 Excel 中创建自己的日期表并将其复制到数据模型中,则尤其如此。 幸运的是,使用 DAX 中的 日期和时间函数 在 Power Pivot 中创建新的日期列非常简单。
提示
如果尚未使用过 DAX,则可以在快速入门开始学习:在 Office.com 上用 30 分钟了解 DAX 基础知识。
DAX 日期和时间函数
如果你曾经在 Excel 公式中使用过日期和时间函数,那么你可能对 日期和时间函数很熟悉。 虽然这些函数与 Excel 中的对应函数类似,但也有一些重要的区别:
- DAX 日期和时间函数使用 datetime 数据类型。
- 它们可以将列中的值作为参数。
- 它们可用于返回和/或操作日期值。
在日期表中创建自定义日期列时经常使用这些函数,因此了解它们非常重要。 我们将使用其中许多函数来创建 Year、Quarter、FiscalMonth 等列。
注意
DAX 中的日期和时间函数与时间智能函数不同。 了解有关 Excel 中 Power Pivot 中的时间智能的详细信息。
DAX 包含以下日期和时间函数:
- 日期
- DATEVALUE
- NEXTDAY
- EDATE
- EOMONTH
- HOUR
- MINUTE
- MONTH
- NOW
- SECOND
- 时间
- TIMEVALUE
- TODAY
- WEEKDAY
- WEEKNUM
- YEAR
- YEARFRAC
还有许多其他 DAX 函数也可在公式中使用。 例如,此处所述的许多公式都使用 数学和三角函数 (如 MOD 和 TRUNC)、 逻辑函数 (如 IF)和 文本函数 (如 FORMAT ) 有关其他 DAX 函数的详细信息,请参阅本文后面的其他 资源 部分。
日历年的公式示例
以下示例介绍用于在名为 Calendar 的日期表中创建其他列的公式。 已存在一个名为 Date 的列,其中包含从 2010/1/1 到 2016/12/31 的连续日期范围。
年
=YEAR ([date])
在此公式中, YEAR 函数从“日期”列中的值返回年份。 因为 Date 列中的值是 datetime 数据类型,所以 YEAR 函数知道如何从中返回年份。
月
=MONTH ([date])
在此公式中,与 YEAR 函数非常类似,我们可以简单地使用 MONTH 函数从“日期”列返回月份值。
季度
=INT ( ([Month]+2) /3)
在本公式中,我们使用 INT 函数以整数形式返回日期值。 我们为 INT 函数指定的参数是月份列中的值,加上 2,然后将其除以 3 以得到季度,从 1 到 4。
月份名称
=FORMAT ([date],“mmmm”)
在此公式中,为了获取月份名称,我们使用 FORMAT 函数将“日期”列中的数值转换为文本。 我们指定 日期 列作为第一个参数,然后指定格式;我们希望月份名称显示所有字符,因此我们使用“mmmm”。 我们的结果如下所示:
如果要返回缩写为三个字母的月份名称,则在格式参数中使用“mmm”。
一周中的某一天
=FORMAT ([date],“ddd”)
在此公式中,我们使用 FORMAT 函数获取日期名称。 因为我们只需要一个缩写的日期名称,所以在 format 参数中指定“ddd”。
示例数据透视表
拥有年、季度、月等日期字段后,就可以在数据透视表或报表中使用它们。 例如,下图显示 VALUES 中的 Sales 事实表中的 SalesAmount 字段,以及 ROWS 中的 Calendar 维度表中的 Year 和 Quarter。 针对年份和季度上下文聚合 SalesAmount。
会计年度的公式示例
Fiscal Year
=IF ([Month]<= 6,[Year],[Year]+1)
在此示例中,会计年度从 7 月 1 日开始。
没有任何函数可从日期值中提取会计年度,因为会计年度的开始日期和结束日期通常与日历年的开始日期和结束日期不同。 为了获取会计年度,我们首先使用 IF 函数来检验 Month 的值是否小于或等于 6。 在第二个参数中,如果 Month 的值小于或等于 6,则返回 Year 列中的值。 如果不是,则返回 Year 中的值并加 1。
指定会计年度结束月份值的另一种方法是创建仅指定月份的度量值。 例如,FYE:=6。 然后,可以引用度量值名称来代替月份编号。 例如,=IF ([月]<=[FYE],[年],[年]+1) 。 这在多个不同的公式中引用会计年度结束月份时提供了更大的灵活性。
Fiscal Month
=IF ([Month]<= 6, 6+[Month], [Month]- 6)
在此公式中,我们指定如果 [Month] 的值小于或等于 6,则采用 6 并将 Month 的值相加,否则从 [Month] 的值中减去 6。
会计季度
=INT ( ([FiscalMonth]+2) /3)
我们用于 FiscalQuarter 的公式与日历年中用于 Quarter 的公式非常相似。 唯一的区别是我们指定 [FiscalMonth] 而不是 [Month]。
节假日或特殊日期
您可能希望包含一个日期列,指示某些日期是假日或其他特殊日期。 例如,你可能希望通过将假日字段添加到数据透视表、作为切片器或筛选器来计算元旦的总销售额的总和。 在其他情况下,您可能希望从其他日期列或度量中排除这些日期。
包括假期或特殊日子非常简单。 可以在 Excel 中创建包含要包含日期的表。 然后,您可以复制或使用“添加到数据模型”,将其作为链接表添加到数据模型。 在大多数情况下,不需要在表和 Calendar 表之间创建关系。 任何引用它的公式都可以使用 LOOKUPVALUE 函数返回值。
下面是在 Excel 中创建的表的示例,其中包含要添加到日期表中的假日:
| 日期 | 假日 |
|---|---|
| 1/1/2010 | 新年 |
| 11/25/2010 | 感恩节 |
| 12/25/2010 | 圣诞节 |
| 2011-1-1 | 新年 |
| 11/24/2011 | 感恩节 |
| 12/25/2011 | 圣诞节 |
| 1/1/2012 | 新年 |
| 2012-11-22 | 感恩节 |
| 12/25/2012 | 圣诞节 |
| 1/1/2013 | 新年 |
| 11/28/2013 | 感恩节 |
| 12/25/2013 | 圣诞节 |
| 11/27/2014 | 感恩节 |
| 12/25/2014 | 圣诞节 |
| 1/1/2014 | 新年 |
| 11/27/2014 | 感恩节 |
| 12/25/2014 | 圣诞节 |
| 1/1/2015 | 新年 |
| 11/26/2014 | 感恩节 |
| 12/25/2015 | 圣诞节 |
| 2016-1-1 | 新年 |
| 11/24/2016 | 感恩节 |
| 12/25/2016 | 圣诞节 |
在日期表中,我们创建一个名为 Holiday 的列,并使用如下公式:
=LOOKUPVALUE (Holidays[Holiday],Holidays[date],Calendar[date])
让我们更仔细地看看这个公式。
我们使用 LOOKUPVALUE 函数从 Holidays 表的 Holiday 列获取值。 在第一个参数中,我们指定结果值所在的列。 我们在 Holidays 表中指定 Holiday 列,因为这是我们要返回的值。
=LOOKUPVALUE (Holidays[Holiday],Holidays[date],Calendar[date])
然后,我们指定第二个参数,即包含要搜索的日期的搜索列。 我们在 Holidays 表中指定日期列,如下所示:
=LOOKUPVALUE (Holidays[Holiday],Holidays[date],Calendar[date])
最后,我们在 Calendar 表中指定包含要在 Holiday 表中搜索的日期的列。 这当然是 Calendar 表中的“日期”列。
=LOOKUPVALUE (Holidays[Holiday],Holidays[date],Calendar[date])
“假日”列将返回日期值与“假日”表中的某个日期匹配的每一行的假日名称。
自定义日历 - 十三个四周期间
某些组织(如零售或食品服务)通常报告不同的时期,例如十三个四周的时期。 对于 13 个四周周期日历,每个周期为 28 天;因此,每个周期包含四个星期一、四个星期二、四个星期三,依此类推。 每个时期包含相同的天数,并且通常,假期将落在每年的同一时间段内。 你可以选择在一周中的任何一天开始一段时间。 与日历或会计年度中的日期类似,可以使用 DAX 创建具有自定义日期的其他列。
在下面的示例中,第一个完整周期从会计年度的第一个星期日开始。 在这种情况下,会计年度从 7 月 1 日开始。
周
此值为我们提供从会计年度第一个完整周开始的周数。 在此示例中,第一个完整周从星期日开始,因此 Calendar 表中第一个会计年度的第一个完整周实际上从 2010 年 7 月 4 日开始,一直持续到 Calendar 表中的最后一个完整周。 虽然此值本身在分析中并不那么有用,但有必要进行计算才能在其他 28 天周期公式中使用。
=INT ([date]-40356) /7)
让我们更仔细地看看这个公式。
首先,我们将创建 Date 列中以整数形式返回值的公式,如下所示:
=INT ([date])
然后,我们想要查找第一个会计年度的第一个星期日。 我们看到现在是 2010 年 7 月 4 日。
现在,将 40356 减去 40356 (,即 2010 年 6 月 27 日的整数,即上一会计年度的最后一个星期日) 该值中,得到自Calendar表中天数开始以来的天数,如下所示:
=INT ([date]-40356)
然后将结果除以一周) 的 7 (天,如下所示:
=INT ( ([date]-40356) /7)
结果如下所示:
句点
此自定义日历中的周期包含 28 天,并且始终从星期日开始。 此列将返回从第一个会计年度的第一个星期日开始的期间数。
=INT ( ([周]+3) /4)
让我们更仔细地看看这个公式。
首先,我们将创建一个公式,将“周”列中的值作为整数返回,如下所示:
= INT ([周])
然后将 3 添加到该值,如下所示:
=INT ([周]+3)
然后将结果除以 4,如下所示:
=INT ( ([周]+3 ) /4)
结果如下所示:
Period Fiscal Year
此值返回期间的会计年度。
=INT ( ([Period]+12) /13) +2008
让我们更仔细地看看这个公式。
首先,我们创建一个公式,它返回 Period 中的值并加 12:
= ([周期]+12)
我们将结果除以 13,因为会计年度中有 13 个 28 天的周期:
= ( ([周期]+12) /13)
我们添加 2010 年,因为这是表中的第一年:
= ( ([Period]+12) /13) +2010
最后,我们使用 INT 函数删除结果的任何分数,并在除以 13 时返回一个整数,如下所示:
= INT ( ([周期]+12) /13) +2010
结果如下所示:
会计年度中的期间
此值返回周期号 1 - 13,从每个会计年度的星期日) 开始的第一个完整周期 (开始。
=IF (MOD ([Period],13) , MOD ([Period],13) ,13)
这个公式有点复杂,所以我们将首先用我们更容易理解的语言来描述它。 此公式指出,将 [Period] 中的值除以 13 可得到一年中 1-13) (周期号。 如果该数字为 0,则返回 13。
首先,我们创建一个公式,用于将该值的余数从 Period 除以 13。 我们可以使用 MOD (数学和三角函数) 如下:
= MOD ([Period],13)
这在大多数情况下为我们提供了我们想要的结果,但 Period 的值为 0 的情况除外,因为这些日期不在第一个财政年度内,例如我们示例 Calendar 日期表的前五天。 我们可以使用 IF 函数来解决这个问题。 如果结果为 0,则返回 13,如下所示:
= IF (MOD ([Period],13) ,MOD ([Period],13) ,13)
结果如下所示:
示例数据透视表
下图显示了一个数据透视表,其中包含 VALUES 中的销售事实表中的 SalesAmount 字段,以及 ROWS 中Calendar 日期维度表中的 PeriodFiscalYear 和 PeriodInFiscalYear 字段。 SalesAmount 按会计年度和会计年度中的 28 天期间针对上下文进行汇总。
关系
在数据模型中创建日期表后,若要开始在数据透视表和报表中浏览数据,并基于日期维度表中的列聚合数据,需要在包含交易数据的事实表和日期表之间创建关系。
由于需要基于日期创建关系,因此需要确保在值为“日期时间” (“日期) ”数据类型的列之间创建该关系。
对于事实数据表中的每个日期值,日期表中的相关查找列必须包含匹配值。 例如,如果“销售”事实 () 表中的“DateKey”列中值为 2012 年 8 月 15 日中午 12:00 的行交易记录,则该日期 (中的相关“日期”列中必须具有对应Calendar) 值。 这是您希望日期表中的日期列包含连续的日期范围的最重要原因之一,其中包括事实表中任何可能的日期。
注意
虽然每个表中的日期列必须 (日期) 具有相同的数据类型,但每列的格式并不重要。
注意
如果 Power Pivot 不允许你在两个表之间创建关系,则日期字段可能无法以相同的精度存储日期和时间。 根据列格式,值可能看起来相同,但存储方式不同。 详细了解如何 使用时间。
注意
避免在关系中使用整数代理键。 从关系数据源导入数据时,日期和时间列通常由代理键表示,代理键是用于表示唯一日期的整数列。 在 Power Pivot 中,应避免使用整数日期/时间键创建关系,而应使用具有日期数据类型的包含唯一值的列。 虽然使用代理键被认为是传统数据仓库中的最佳做法,但 Power Pivot 不需要整数键,这导致很难按不同的日期周期对数据透视表中的值进行分组。
如果在尝试创建关系时遇到“类型不匹配”错误,则可能是因为事实表中的列不是“日期”数据类型。 当 Power Pivot 无法自动将非日期 (通常是文本数据类型) 转换为日期数据类型时,就会发生这种情况。 您仍然可以在事实表中使用该列,但您必须在新的计算列中使用 DAX 公式转换数据。 请参阅附录后面的 将文本数据类型日期转换为日期数据类型 。
多个关系
在某些情况下,可能需要创建多个关系或创建多个日期表。 例如,如果 Sales 事实数据表中有多个日期字段(例如 DateKey、ShipDate 和 ReturnDate),则这些字段都可以与 Calendar 日期表中的“日期字段有关系,但其中只有一个可以是活动关系。 在这种情况下,因为 DateKey 表示交易日期,因此是最重要的日期,所以这最适合作为 活动 关系。 其他人的关系处于非活动状态。
以下数据透视表按会计年度和会计季度计算总销售额。 将名为“总销售额”的度量值,公式为 Total Sales:=SUM ([SalesAmount]) ,置于 VALUES 中,而 Calendar 日期表中的 FiscalYear 和 FiscalQuarter 字段置于 ROWS 中。
这个简单的数据透视表可以正常工作,因为我们希望按照 DateKey 中的 交易日期 对总销售额进行求和。 我们的“总销售额”度量值使用 DateKey 中的日期,并按会计年度和会计季度求和,因为 Sales 表中的 DateKey 与 Calendar 日期表中的 Date 列之间存在关系。
非活动关系
但是,如果我们不想按交易日期而是按 发货日期计算总销售额呢? 我们需要在 Sales 表的 ShipDate 列和 Calendar 表中的 Date 列之间建立关系。 如果我们不创建该关系,我们的聚合将始终基于交易日期。 但是,我们可以有多个关系,即使只有一个关系可以处于活动状态,并且由于事务日期是最重要的,因此它获取与 Calendar 表的活动关系。
在这种情况下,ShipDate 具有非活动关系,因此为基于发货日期聚合数据而创建的任何度量值公式都必须使用 USERELATIONSHIP 函数指定非活动关系。
例如,由于 Sales 表中的 ShipDate 列与 Calendar 表中的 Date 列之间存在非活动关系,因此我们可以创建一个度量值,按发货日期对总销售额进行求和。 我们使用如下公式来指定要使用的关系:
Total Sales by Ship Date:=CALCULATE (SUM (Sales[SalesAmount]) , USERELATIONSHIP (Sales[ShipDate], Calendar[Date]) )
此公式简单指出: 计算 SalesAmount 的总和,但使用 Sales 表中的 ShipDate 列与 Calendar 表中 Date 列之间的关系进行筛选。
现在,如果我们创建数据透视表并将“按发货日期列出的总销售额”度量值放入“值”中,将“会计年度和会计季度”放在 ROWS 上,我们将看到相同的“总计”,但会计年度和会计季度的所有其他总和金额不同,因为它们基于发货日期而不是交易日期。
列出
使用非活动关系只允许使用一个日期表,但它确实要求任何度量值 (如“按发货日期) 列出的总销售额”)在其公式中引用非活动关系。 还有另一种选择,即使用多个日期表。
多个日期表
处理事实表中的多个日期列的另一种方法是创建多个日期表,并在它们之间创建单独的活动关系。 让我们再次查看 Sales 表示例。 我们有三列,其中包含我们可能想要聚合数据的日期:
- 包含每笔交易的销售日期的 DateKey。
- 发货日期 – 已售商品发货给客户的日期和时间。
- 退货日期 – 收到一个或多个退回项目的日期和时间。
请记住,包含交易日期的 DateKey 字段非常重要。 我们将根据这些日期进行大部分聚合,因此我们肯定希望它与 Calendar 表中的 Date 列之间存在关系。 如果我们不想在 ShipDate 和 ReturnDate 与 Calendar 表中的 Date 字段之间创建非活动关系,从而需要特殊度量值公式,我们可以为发货日期和退货日期创建其他日期表。 然后,我们可以在它们之间建立积极的关系。
在此示例中,我们创建了另一个名为 ShipCalendar 的日期表。 当然,这也意味着创建额外的日期列,并且由于这些日期列位于不同的日期表中,因此我们希望以将它们与 Calendar 表中的相同列区分开来的方式命名它们。 例如,我们创建了名为 ShipYear、ShipMonth、ShipQuarter 等的列。
如果我们创建数据透视表并将“总销售额”度量值放在 VALUES 中,将 ShipFiscalYear 和 ShipFiscalQuarter 放在 ROWS 上,我们将看到的结果与创建非活动关系和特殊的“按发货日期列出的总销售额”计算字段时看到的相同。
每种方法都需要仔细考虑。 将多个关系用于单个日期表时,可能必须创建使用 USERELATIONSHIP 函数传输非活动关系的特殊度量值。 另一方面,在字段列表中创建多个日期表可能会造成混乱,并且由于数据模型中有更多表,因此需要更多内存。 试验最适合你的方法。
日期表属性
“日期表”属性设置 Time-Intelligence 函数(如 TOTALYTD、PREVIOUSMONTH 和 DATESBETEN)正常工作所需的元数据。 使用上述函数之一运行计算时,PowerPivot 的公式引擎知道从何处获取所需的日期。
警告
如果未设置此属性,则使用 DAX Time-Intelligence 函数的度量值可能不会返回正确的结果。
设置“日期表”属性时,可在其中指定日期表和日期 (日期时间) 数据类型的日期列。
如何:设置日期表属性
- 在 PowerPivot 窗口中,选择“Calendar”表。
- 在 “设计 ”选项卡上,单击“ 标记为日期表”。
- 在“标记为日期表”对话框中,选择具有唯一值和“日期”数据类型的列。
使用时间
在 Excel 或 SQL Server 中具有“日期”数据类型的所有日期值实际上都是一个数字。 该数字中包括表示时间的数字。 在许多情况下,每一行的时间都是午夜。 例如,如果“销售事实”表中的 DateTimeKey 字段的值类似于 10/19/2010 12:00:00 AM,则表示值的精确度级别为日级别。 如果 DateTimeKey 字段值包含时间,例如 10/19/2010 8:44:00 AM,这意味着值的精确度级别为分钟。 值也可以是小时级别精度,甚至是秒级精度级别。 时间值的精度级别将对创建日期表的方式及其与事实表之间的关系产生重大影响。
您需要确定是将数据聚合到日精度级别还是时间精度级别。 换言之,你可能希望将日期表中的列(如上午、下午或小时)用作数据透视表的行、列或筛选器区域中的时间日期字段。
注意
天是 DAX Time Intelligence 函数可以使用的最小时间单位。 如果不需要使用时间值,则应降低数据的精度以将天用作最小单位。
如果您打算将数据聚合到时间级别,则您的日期表将需要一个包含时间的日期列。 事实上,对于日期范围内的每一年,它将需要一个日期列,其中每一小时,甚至每分钟都有一行。 这是因为,若要在事实数据表的 DateTimeKey 列和日期表的日期列之间创建关系,必须具有匹配值。 正如您可以想象的那样,如果您包括很多年份,这可以成为一个非常大的日期表。
但在大多数情况下,您只想汇总当天的数据。 换言之,你将使用年、月、周或星期几等列作为数据透视表的行、列或筛选器区域中的字段。 在这种情况下,日期表中的日期列只需为一年中的每一天包含一行,如前所述。
如果您的日期列包含时间级别的精度,但您只会聚合到一天级别,为了在事实表和日期表之间创建关系,您可能必须通过创建一个新列来修改事实表,该列将日期列中的值截断为日期值。 换言之,将 10/19/2010 8:44:00AM 之类的值转换为 10/19/2010 12:00:00 AM。 然后,可以在此新列和日期表中的日期列之间创建关系,因为值匹配。
我们来看一个示例。 此图显示了“销售”事实数据表中的 DateTimeKey 列。 通过使用 Calendar 日期表中的列(如年、月、季度等),此表中数据的所有聚合只需到日级别。值中包含的时间不相关,仅与实际日期相关。
由于我们不需要对这些数据进行时间级别分析,因此我们不需要 Calendar 日期表中的“日期”列为每年每天的每一小时和每一分钟包含一行。 因此,日期表中的“日期”列如下所示:
若要在 Sales 表的 DateTimeKey 列和 Calendar 表中的 Date 列之间创建关系,我们可以在 Sales 事实表中创建一个新的计算列,并使用 TRUNC 函数将 DateTimeKey 列中的日期和时间值截断为与 Calendar 表中 Date 列中的值匹配的日期值。 我们的公式如下所示:
=TRUNC ([DateTimeKey],0)
这为我们提供了一个新列 (我们命名为 DateKey) ,其中包含 DateTimeKey 列中的日期,并且每行的时间为 12:00:00 AM:
现在,我们可以在这个新的 (DateKey) 列和 Calendar 表中的 Date 列之间创建关系。
同样,我们可以在 Sales 表中创建一个计算列,将 DateTimeKey 列中的时间精度降低到小时精度级别。 在这种情况下,TRUNC 函数将不起作用,但我们仍然可以使用其他 DAX 日期和时间函数提取新值并将其重新连接到小时精度级别。 我们可以使用如下公式:
= DATE (YEAR ([DateTimeKey]) , MONTH ([DateTimeKey]) , DAY ([DateTimeKey]) ) + TIME (HOUR ([DateTimeKey]) , 0, 0)
我们的新列如下所示:
如果日期表中的“日期”列具有小时精度级别的值,则可以在它们之间创建关系。
使日期更可用
在日期表中创建的许多日期列对于其他字段都是必需的,但在分析中并不是那么有用。 例如,我们在本文中引用和显示的“销售”表中的 DateKey 字段非常重要,因为对于每个交易,该交易记录为发生在特定日期和时间。 但从分析和报告的角度来看,它并没有那么有用,因为我们不能将其用作数据透视表或报告中的行、列或筛选器字段。
同样,在我们的示例中,Calendar 表中的“日期”列非常有用,事实上至关重要,但不能将其用作数据透视表中的维度。
若要使表及其中的列尽可能有用,并使数据透视表或 Power View 报表字段列表更易于导航,请务必在客户端工具中隐藏不必要的列。 可能还需要隐藏某些表。 前面显示的“假日”表包含对 Calendar 表中某些列很重要的假日日期,但“假日”表中的“日期”和“假日”列不能用作数据透视表中的字段。 同样,为了使字段列表更易于导航,可以隐藏整个假日表。
使用日期的另一个重要方面是命名约定。 可以根据需要命名 Power Pivot 中的表和列。 但请记住,特别是如果要与其他用户共享工作簿,良好的命名约定便于识别表和日期,不仅在字段列表中,而且在 Power Pivot 和 DAX 公式中也是如此。
在数据模型中拥有日期表后,您可以开始创建有助于充分利用数据的度量值。 有些可能像对当年的销售总额求和一样简单,而另一些则可能更为复杂,您需要在其中筛选特定范围的唯一日期。 有关详细信息,请参阅 Power Pivot 和时间智能函数中的度量值。
附录
将文本数据类型日期转换为日期数据类型
在某些情况下,包含交易记录数据的事实表可能包含文本数据类型的日期。 也就是说,显示为 2012-12-04T11:47:09 的日期实际上根本不是日期,或者至少不是 Power Pivot 能够理解的日期类型。 它实际上只是读起来像日期的文本。 要在事实表中的日期列和日期表中的日期列之间创建关系,两列都必须是 “日期 ”数据类型。
通常情况下,在尝试将文本数据类型的日期列的数据类型更改为日期数据类型时,Power Pivot 可以解释日期并将其自动转换为真正的日期数据类型。 如果 Power Pivot 无法执行数据类型转换,您将收到类型不匹配错误。
但是,您仍然可以将日期转换为真正的日期数据类型。 可以创建新的计算列,并使用 DAX 公式从文本字符串中分析年、月、日、时间等,然后以 Power Pivot 可以读取为真实日期的方式将其连接起来。
在此示例中,我们将名为 Sales 的事实数据表导入到 Power Pivot 中。 它包含名为 DateTime 的列。 值显示如下所示:
如果我们在“格式”组中查看数据类型,Power Pivot 的“开始”选项卡会发现它是“文本”数据类型。
由于数据类型不匹配,我们无法在日期时间列和日期列之间创建关系。 如果尝试将数据类型更改为 “日期”,将收到类型不匹配错误:
在这种情况下,Power Pivot 无法将数据类型从文本转换为日期。 我们仍然可以使用此列,但要将其转换为真正的日期数据类型,我们需要创建一个新列,用于分析文本并将其重新创建为 Power Pivot 可以设置为“日期”数据类型的值。
请记住,来自本文前面的“使用时间”部分;除非需要您的分析达到一天中的时间精度级别,否则您应该将事实数据表中的日期转换为日期精度级别。 考虑到这一点,我们希望新列中的值处于日级别的精度 (不包括时间) 。 可以使用以下公式将 DateTime 列中的值转换为日期数据类型,并删除时间精度级别:
=DATE (LEFT ([DateTime],4) , MID ([DateTime],6,2) , MID ([DateTime],9,2) )
在本例中,这为我们提供了一个名为“日期) ”的新列 (。 Power Pivot 甚至可以检测为日期的值,并自动将数据类型设置为日期。
如果我们想保持时间级别的精度,我们只需扩展公式以包含小时、分钟和秒。
=DATE (LEFT ([DateTime],4) , MID ([DateTime],6,2) , MID ([DateTime],9,2) ) +
TIME (MID ([DateTime],12,2) , MID ([DateTime],15,2) , MID ([DateTime],18,2) )
现在我们有了日期数据类型的日期列,我们可以在它和日期中的日期列之间创建关系。