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