简介

已完成

可以编写一个数据分析表达式 (DAX) 公式,向模型添加计算表。 该公式可以复制或转换现有模型数据,以生成一个新表。

注意

计算表不能连接到外部数据;必须使用 Power Query 来完成这个任务。

计算表公式必须返回一个表对象。 最简单的公式可以复制一个现有模型表。

计算表是有成本的:计算表增加了模型的存储大小,并且会延长数据刷新时间。 原因在于,当计算表与刷新表有公式依赖关系时,它们会重新计算。

复制表

以下介绍一个常见设计问题,可通过创建计算表来解决。 首先,应下载并打开 Adventure Works DW 2020 M03.pbix 文件,然后切换到模型关系图。

请注意,在模型图中,Sales 表与 Date 表之间存在三种关系。

模型关系图显示了三种关系,因为 Sales 表按订单日期、发货日期和截止日期存储销售数据。 如果检查 OrderDateKey、ShipDateKey 和 DueDateKey 列,注意到有一个关系用实线表示,这是活动关系。 用虚线表示的其他关系是非活动关系。

注意

在任意两个模型表之间只能存在一个活动关系。

在关系图中,将光标悬停在活动关系上以突出显示相关列,通过与模型关系图交互来了解相关列。 在本例中,活动关系筛选 Sales 表中的 OrderDateKey 列。 因此,应用于 Date 表的筛选器将传播到 Sales 表以按订单日期进行筛选;它们永远不会按发货日期或截止日期进行筛选。

下一步是删除 Date 表和 Sales 表之间的两个非活动关系。 要删除一个关系,右键单击它,然后在上下文菜单中选择“删除”。 确认删除这两个非活动关系。

接下来,添加一个新表,使报表用户能够按发货日期筛选销售额。 切换到“报表”视图,然后在“建模”功能区选项卡的“计算”组中,选择“新建表”。

在编辑栏(位于功能区下方)中,输入以下计算表定义,然后按 Enter。

Ship Date = 'Date'

计算表定义会复制 Date 表数据,以生成名为 Ship Date 的新表。 Ship Date 表中的列和行与 Date 表完全相同。 当 Date 表数据刷新时,Ship Date 表将重新计算,因此它们将始终保持同步。

切换到模型关系图,可以看到增加了 Ship Date 表。

接下来,在 Ship Date 表中的 DateKey 列和 Sales 表中的 ShipDateKey 列之间创建一个关系。 将 Ship Date 表中的 DateKey 列拖动到 Sales 表中的 ShipDateKey 列上即可创建关系。

计算表只复制数据;它不会复制任何模型属性或对象(如列可见性或层次结构)。 如果需要的话,你需要为新表设置这些项。

提示

可以对计算表的列进行重命名。 在本例中,建议对列进行重命名,使其更好地描述其用途。 例如,可以将 Ship Date 表中的 Fiscal Year 列重命名为 Ship Fiscal Year。 相应地,当在视觉对象中使用 Ship Date 表中的字段时,它们的名称会自动包含在标题栏(如视觉对象标题或轴标签)中。

要完成 Ship Date 表的设计,可以执行以下操作:

  • 为以下列重命名:
    • 将 Date 重命名为 Ship Date
    • 将 Fiscal Year 重命名为 Ship Fiscal Year
    • 将 Fiscal Quarter 重命名为 Ship Fiscal Quarter
    • 将 Month 重命名为 Ship Month
    • 将 Full Date 重命名为 Ship Full Date
  • 按 Ship Date 列对 Ship Full Date 列进行排序。
  • 按 MonthKey 列对 Ship Month 列进行排序。
  • 隐藏 MonthKey 列。
  • 创建名为“Fiscal”的层次结构,其中包含以下级别:
    • Ship Fiscal Year
    • Ship Fiscal Quarter
    • Ship Month
    • Ship Full Date
  • 使用 Ship Date 列将 Ship Date 表标记为日期表。

如前面所述,当两个表之间存在多种关系时,计算表非常有用。 你还可以使用计算表向模型添加日期表。 Date 表需要应用被称为“时间智能”的特殊时间筛选器。

创建日期表

在下一个示例中,将创建第二个计算表,这次使用 CALENDARAUTO DAX 函数。

使用以下定义创建 Due Date 计算表。

Due Date = CALENDARAUTO(6)

CALENDARAUTO DAX 函数采用一个可选参数,即一年的最后一个月份,并返回一个单列表。 如果未传入月份,则假定它为 12(表示 12 月)。 例如,在 Adventure Works,他们的会计年度于每年 6 月 30 日结束,因此,传入的值是 6(表示 6 月)。

该函数扫描模型中的所有日期和日期/时间列,以确定最早和最新存储的日期值。 然后,它会生成一组完整的日期,这些日期跨越模型中的所有日期,确保加载整年的日期。 例如,如果你的模型中存储的最早日期是 2021 年 10 月 15 日,则 CALENDARAUTO 函数返回的第一个日期将是 2021 年 7 月 1 日。 如果模型中存储的最新日期是 2022 年 6 月 15 日,则 CALENDARAUTO 函数返回的最新日期将是 2022 年 6 月 30 日。

实际上,CALENDARAUTO 函数确保可以满足以下要求以标记一个日期表:

  • 该表必须包含一个数据类型为 Date 的列。
  • 列必须包含完整的年份。
  • 列不能缺少日期。

提示

你还可使用 CALENDAR DAX 函数,并传入两个表示日期范围的日期值来创建日期表。 函数为范围内的每个日期生成一行。 你可以传入静态日期值,也可以传入表达式以从模型中的特定列检索最早/最新日期。

接下来,切换到数据视图,然后在“字段”窗格中,选择“Due Date”表。 现在,查看日期的列。 可能需要通过选择“Date”列标题内的箭头,然后按升序排序,以查看第一行中的最早日期。

注意

排序或筛选列不会改变值的存储方式。 这些功能可帮助你浏览和理解数据。

现在选择了 Date 列,请查看状态栏中的消息(位于左下角)。 它说明了表存储的行数,以及在所选列中发现的非重复值的数目。

当表的行数和非重复值的数量相同时,表示列包含唯一值。 这个因素很重要,有两个原因:它满足了标记日期表的要求,并允许将此列用作模型关系中的一方。

每当包含日期列的表刷新时,Due Date 计算表都会重新计算。 换句话说,如果将某一行加载到订单日期为 2022 年 7 月 1 日的 Sales 表中,Due Date 表将自动延长到包括下一年的结束日(2023 年 6 月 30 日)之前的日期。

Due Date 表需要额外的列来支持已知的筛选和分组要求,具体取决于按年、按季度还是按月。