Power BI Desktop 中的数据类型

本文介绍 Power BI Desktop 和 Data Analysis Expressions (DAX) 支持的数据类型。

Power BI 加载数据时,会尝试将源列的数据类型转换为支持更高效的存储、计算和数据可视化的数据类型。 例如,如果从 Excel 导入的值的列没有小数值,Power BI Desktop 会将整个数据列转换为整数数据类型,这能更好地存储整数。

这一概念很重要,因为某些 DAX 函数具有特殊的数据类型要求。 在许多情况下,DAX 隐式转换数据类型,但在某些情况下不会。 例如,如果 DAX 函数需要日期数据类型,而你的列的数据类型为文本,DAX 函数将不能正常工作。 因此,务必要对列使用正确的数据类型,这很有用。

确定并指定列的数据类型

在 Power BI Desktop 中,你可以在 Power Query 编辑器、数据视图或报表视图中确定并指定列的数据类型:

  • 在 Power Query 编辑器中,选择列,然后在功能区的“转换”组中选择“数据类型”。

    Screenshot of the Power Query Editor, showing the Data type dropdown selection.

  • 在“数据视图”或“报表视图”中,选择列,然后选择功能区“列工具”选项卡上“数据类型”旁边的下拉箭头。

    Screenshot of Data View, showing the Data type dropdown selection.

Power Query 编辑器中的“数据类型”下拉列表选项中有两种数据类型在数据视图或报表视图中不存在,分别是“日期/时间/时区”和“持续时间”。 将具有这些数据类型的列加载到 Power BI 模型中时,“日期/时间/市区”列将转换为“日期/时间”数据类型,而“持续时间”列将转换为“十进制数”数据类型。

在 Power Query 编辑器外部不支持“二进制”数据类型。 在 Power Query 编辑器中,如果先将二进制文件转换为其他数据类型,然后再将它加载到 Power BI 模型,则可以在加载这些文件时使用“二进制”数据类型。 由于遗留原因,“二进制”选项存在于数据视图和报表视图菜单中,但如果尝试将“二进制”列加载到 Power BI 模型,则可能会遇到错误。

数字类型

Power BI Desktop 支持三种数字类型:十进制数、定点十进制数和整数。

可以使用表格对象模型 (TOM) 列的 DataType 属性指定数字类型的 DataType 枚举。 有关如何以编程方式修改 Power BI 中的对象的详细信息,请参阅使用表格对象模型对 Power BI 语义模型进行编程

十进制数

“十进制数”是最常见的数字类型,可以处理具有小数值和整数的数字。 “十进制数”表示 64 位(八字节)浮点数,其负值从 -1.79E +308 到 -2.23E -308,正值从 2.23E -308 到 1.79E +308,以及 0。 例如,34、34.01 和 34.000367063 等数字都是有效的十进制数。

“十进制数”类型可以表示的最高精度为 15 位。 小数分隔符可出现在数字的任意位置。 此类型对应于 Excel 存储其数字的方式,TOM 将此类型指定为 DataType.Double 枚举。

定点小数

“定点十进制数”数据类型的十进制分隔符位置是固定的。 十进制分隔符右侧始终有四位数,并可以表示有意义的 19 位数。 “定点十进制数”可以表示的最大值为正负 922,337,203,685,477.5807。

定点十进制数类型在舍入可能会引发错误的情况下非常有用。 带小数值的数字有时会累加并迫使一个数字略微不准确。 通过截断十进制分隔符右侧四位数后的数字,“定点十进制数”类型可以帮助你避免此类错误。

此数据类型可对应于 SQL Server 的十进制 (19,4),或 Analysis Services 中的货币数据类型和 Excel 中的 Power Pivot。 TOM 将此类型指定为 DataType.Decimal 枚举。

整数

整数表示 64 位(八字节)整数值。 由于它是一个整数,因此整数小数位右侧没有数字。 此类型允许 19 位介于 -9,223,372,036,854,775,807 (-2^63+1) 和 9,223,372,036,854,775,806 (2^63-2) 之间的正负整数,因此可以表示数值数据类型的最大可能数字。

与“定点十进制数”类型相同,在需要控制舍入的情况下,整数类型非常有用。 TOM 将“整数”数据类型表示为 DataType.Int64 枚举。

注意

Power BI Desktop 数据模型支持 64 位整数值,但由于存在 JavaScript 限制,视觉对象可安全表达的最大数字是 9,007,199,254,740,991 (2^53-1)。 如果数据模型具有较大的数字,可以在将其添加到视觉对象之前通过计算减小其大小。

数字类型计算的准确性

根据浮点数的 IEEE 754 标准,“十进制数”数据类型的列值存储为“近似”数据类型。 “近似”数据类型在精度方面存在固有限制,因为它们可能被存储为非常接近或舍入的近似值,而不是存储确切的数值。

如果浮点值无法可靠地量化浮点位数,则可能会出现精度损失或不精确。 在一些报告的场景中,不精确可能表现为意外或不准确的计算结果。

在“十进制数”数据类型的值之间执行等式相关比较的计算可能会返回意外结果。 等式比较包括等于 =、大于 >、小于 <、大于或等于 >=以及小于或等于 <=

该问题在 DAX 表达式中使用 RANKX 函数时最为明显,该表达式计算结果两次,导致数字略有不同。 报表用户可能不会注意到这两个数字之间的差异,但排名结果会显而易见地不准确。 为避免意外结果,你可以将列数据类型从“十进制数”更改为“定点十进制数”或“整数”,或者使用 ROUND 强制舍入。 “定点十进制数”数据类型具有更高的精度,因为十进制分隔符右侧始终有四位数。

对“十进制数”数据类型的列值进行求和的计算很少会返回意外结果。 此结果很可能出现在同时具有大量正数和负数的列中。 求和结果受列中各行值分布的影响。

如果所需的计算在对大多数负数求和之前对大多数正数求和,则开头的大部分正和可能会使结果偏斜。 如果计算恰好添加了平衡的正数和负数,则查询将保留更高的精度,因此返回更准确的结果。 为避免出现意外结果,你可以将列数据类型从“十进制数”更改为“定点十进制数”或“整数”。

日期/时间类型

Power BI Desktop 支持 Power Query 编辑器中的五种“日期/时间”数据类型。 “日期/时间/时区”和“持续时间”在加载期间都转换为 Power BI Desktop 数据模型。 该模型支持“日期/时间”,也可以单独将值的格式设置为“日期”或“时间”。

  • 日期/时间 – 表示日期和时间值。 基础“日期/时间”值存储为“十进制数字”类型,因此可以在这两种类型之间进行转换。 时间部分存储为 1/300 秒 (3.33 ms) 的整数倍的分数。 数据类型支持介于 1900 年和 9999 年之间的日期。

  • “日期”仅表示日期,没有时间部分。 “日期”转换为模型时,其值与分数位是零的“日期/时间”值相同。

  • “时间”仅表示时间,没有日期部分。 “时间”转换为模型时,其值与小数点左侧没有数字的“日期/时间”值相同。

  • “日期/时间/时区”表示具有时区偏移量的 UTC 日期/时间,并在加载到模型中时转换为“日期/时间”。 Power BI 模型不会根据用户的位置或区域设置调整时区。 在美国将值 09:00 加载到模型中时,无论在何处打开或查看报表,它都将显示为 09:00。

  • “持续时间”表示时间长度,并在加载到模型中时转换为“十进制数”类型。 对于“十进制数字”类型,可以在具有正确结果的“日期/时间”值中添加或减去值,并在显示数量级的可视化效果中轻松使用这些值。

文本类型

“文本”数据类型是 Unicode 字符数据字符串,可以是字母、数字或以文本格式表示的日期。 根据 Power BI 的 Power Query 基础引擎及其对“文本”数据类型长度的限制,字符串长度的实际最大限制约为 32,000 个 Unicode 字符。 “文本”数据类型超出实际最大限制可能会导致错误。

在某些情况下,Power BI 存储文本数据的方式可能会导致数据以不同方式显示。 后续部分介绍可能导致“文本”数据在查询 Power Query 编辑器数据和将其加载到 Power BI 之间外观略有更改的常见情况。

事例敏感性

在 Power BI 中存储和查询数据的引擎不区分大小写,并将字母的不同大小写形式视为相同值。 “A”等于“a”。 但是,Power Query 区分大小写,其中“A”与“a”不同。 区分大小写的差异可能会导致文本数据在加载到 Power BI 后似乎莫名其妙地更改大小写的情况。

以下示例显示订单数据:每个订单唯一的“OrderNo”列,以及显示下单时手动输入的收件人姓名的“收件人”列。 Power Query 编辑器显示多个订单,这些订单在系统中输入的收件人姓名不同,其大小写也不同。

Screenshot of textual data with various capitalizations in Power Query

Power BI 加载数据后,“数据”选项卡中重复名称的大小写从原始条目更改为大小写变体之一。

Screenshot that shows the textual data with changed capitalization after loading into Power BI.

发生此更改是由于 Power Query 编辑器区分大小写,因此它显示的数据与源系统中存储的数据完全相同。 在 Power BI 中存储数据的引擎不区分大小写,因此将字符的小写和大写版本视为相同。 加载到 Power BI 引擎的 Power Query 数据可能会相应地更改。

Power BI 引擎在加载数据时从顶部开始单独计算每一行。 对于每个文本列(如“收件人”),引擎存储一个唯一值字典,以通过数据压缩提高性能。 引擎将“收件人”列中的前三个值视为唯一值,并将其存储在字典中。 之后,由于引擎不区分大小写,因此它会将名称计算为相同结果。

引擎将名称“Taina Hasu”视为与“TAINA HASU”和“Taina HASU”相同的名称,因此它不存储这些变体,而是引用它存储的第一个变体。 名称“MURALI DAS”以大写字母显示,因为这是引擎在从上到下加载数据时第一次计算它时的名称。

下图演示了计算过程:

Diagram that shows the data load process and mapping text values to a dictionary of unique values.

在上面的示例中,Power BI 引擎加载第一行数据,创建“收件人”字典并将“Taina Hasu”添加到其中。 引擎还在加载的表的“收件人”列中添加对该值的引用。 引擎对第二行和第三行执行相同操作,因为这些名称在忽略大小写时不等效于其他名称。

对于第四行,引擎将值与字典中的名称进行比较,并查找名称。 由于引擎不区分大小写,因此“TAINA HASU”和“Taina Hasu”是相同的。 引擎不会向字典添加新名称,而是引用现有名称。 其余行也会发生相同的过程。

注意

由于在 Power BI 中存储和查询数据的引擎不区分大小写,因此在使用区分大小写源的 DirectQuery 模式下工作时要特别小心。 Power BI 假定源已消除重复行。 由于 Power BI 不区分大小写,因此它将只因大小写而不同的两个值视为重复值,而源不会将它们视为重复值。 在这种情况下,最终结果未定义。

为了避免这种情况,如果将 DirectQuery 模式用于区分大小写的数据源,请在源查询或 Power Query 编辑器中规范化大小写。

前导空格和尾随空格

Power BI 引擎会自动剪裁文本数据后面的任何尾随空格,但不会删除数据前面的前导空格。 为避免混淆,在处理包含前导空格或尾随空格的数据时,应使用 Text.Trim 函数删除文本开头或结尾的空格。 如果不删除前导空格,可能会因为值重复而无法创建关系,或者视觉对象可能会返回意外结果。

下面的示例展示了客户相关数据:“名称”列(其中包含客户名称)和“索引”列(对于每个条目都是唯一的)。 为清楚起见,名称显示在引号内。 客户名称重复了四次,但每次都包含不同的前导空格和尾随空格组合。 随着时间的推移,手动输入数据可能会出现这些变化。

前导空格 尾随空格 名称 索引 文本长度
1 “Dylan Williams” 1 14
2 “Dylan Williams ” 10 15
3 “ Dylan Williams” 20 15
4 “ Dylan Williams ” 40 16

在 Power Query 编辑器中,生成的数据如下所示。

Screenshot of textual data with various leading and trailing spaces in Power Query Editor.

加载数据后转到 Power BI 中的“数据”选项卡时,同个表如下图所示,其行数与之前相同。

Screenshot of the same textual data after loading into Power BI returns the same number of rows as before.

但是,基于此数据的视觉对象仅返回两行。

Screenshot of a table visual based on the same data returning just two lines of data.

在上图中,第一行总“索引”字段值为 60,因此视觉对象中的第一行表示已加载数据的最后两行。 第二行总“索引”值为 11,表示前两行。 视觉对象和数据表之间的行数差异是由引擎自动删除(或剪裁)尾随空格,而不是前导空格所致。 因此,引擎对第一行和第二行以及第三行和第四行求值相同,视觉对象则返回这些结果。

此行为还可能导致与关系相关的错误消息,因为检测到重复值。 例如,根据关系配置,你可能会看到类似于下图的错误:

Screenshot of an error message about duplicate values.

在其他情况下,可能无法创建多对一或一对一关系,因为检测到重复值。

Screenshot of the relationship dialog showing a 'the cardinality you selected isn't valid for this relationship' error, which is related to duplicate values being detected.

可以将这些错误追溯到前导空格或尾随空格,并使用 Text.Trim 或“转换”下的 Trim 删除 Power Query 编辑器中的空格来解决这些问题。

True/False 类型

True/false 数据类型是 True 或 False 的布尔值。 为了获得最佳和最一致的结果,将包含布尔信息 true/false 的列加载到 Power BI 中时,请将列类型设置为“True/False”。

Power BI 在某些情况下转换和显示数据的方式不同。 本部分介绍转换布尔值的常见情况,以及如何处理在 Power BI 中产生意外结果的转换。

在此示例中,你将加载有关客户是否已注册新闻稿的数据。 值 TRUE 表示客户已注册该新闻稿,而值 FALSE 表示客户尚未注册。

但是,当你将报表发布到 Power BI 服务时,新闻稿订阅状态列显示为 0 和 -1,而不是预期值 TRUE 或 FALSE 。 以下步骤介绍了此转换是如何发生的,以及如何阻止它。

此表的简化查询如下图所示:

Screenshot that shows columns set to Boolean.

“订阅新闻稿”列的数据类型设置为“任何”,因此,Power BI 将数据以“文本”的形式加载到模型中。

Screenshot showing the data loaded into Power BI.

当你添加显示每个客户详细信息的简单可视化效果时,数据会按预期显示在视觉对象中,无论是在 Power BI Desktop 中还是在发布到 Power BI 服务时,都是如此。

Screenshot of a visual that shows the data appearing as expected.

但是,当你刷新 Power BI 服务中的语义模型时,视觉对象中的“订阅新闻稿”列将值显示为 -1 和 0,而不是将其显示为 TRUE 或 FALSE

Screenshot of a visual that shows data appearing in an unexpected format after refresh.

如果从 Power BI Desktop 重新发布报表,“订阅新闻稿”列将再次按预期显示 TRUE 或 FALSE,但是一旦 Power BI 服务中发生刷新,这些值将再次更改为显示 -1 和 0。

防止这种情况的解决方案是在 Power BI Desktop 中将任何布尔列设置为“True/False”类型,然后重新发布报表。

Screenshot of changing the data type of the column to True/False.

进行更改时,可视化效果显示“订阅新闻稿”列中的值略有不同。 文本不是在表中输入的全大写字母,而是只将第一个字母大写。 此更改是更改列数据类型的一个结果。

Screenshot of values appearing differently when you change the data type.

一旦更改数据类型并将其重新发布到 Power BI 服务,且发生刷新时,报表将按预期显示值 True 或 False。

Screenshot that shows true or false values that use the True/false data type appear as expected after refresh.

总之,在 Power BI 中处理布尔数据时,请确保在 Power BI Desktop 中将列设置为“True/False”数据类型。

空白类型

“空白”是表示和替代 SQL null 的 DAX 数据类型。 你可以使用 BLANK 函数创建空白,并使用 ISBLANK 逻辑函数对其进行测试。

Binary 类型

可使用“二进制”数据类型来表示具有二进制格式的任何数据。 在 Power Query 编辑器中,如果先将二进制文件转换为其他数据类型,然后再将它加载到 Power BI 模型,则可以在加载这些文件时使用此数据类型。

Power BI 数据模型中不支持二进制列。 由于遗留原因,“二进制”选项存在于数据视图和报表视图菜单中,但如果尝试将“二进制”列加载到 Power BI 模型,则可能会遇到错误。

注意

如果二进制列处于查询步骤的输出中,则尝试通过网关刷新数据可能会导致错误。 建议在查询的最后一个步骤中显式删除任何二进制列。

表类型

DAX 在许多函数中使用表数据类型,例如聚合和时间智能计算。 某些函数需要引用表。 其他函数返回一个表,然后可以将该表作为其他函数的输入。

在某些需要表作为输入的函数中,你可以指定计算结果为表格的表达式。 一些函数需要引用基表。 有关特定函数要求的详细信息,请参阅 DAX 函数引用

隐式和显式数据类型转换

每个 DAX 函数都对作为输入和输出的数据类型有特定要求。 例如,某些函数要求对部分参数使用整数,而其他部分使用日期。 另外一些函数则要求使用文本或表。

如果将列中与该函数所需数据类型不兼容的数据指定为参数,DAX 可能会返回错误信息。 但只要有可能,DAX 会尝试将数据隐式转换为所需的数据类型。

例如:

  • 如果以字符串形式键入日期,DAX 会分析该字符串并尝试将其转换为 Windows 日期和时间格式之一。
  • 你可以添加 TRUE+1 并获得结果 2,因为 DAX 将 TRUE 隐式转换为数字 1,并执行 1+1 运算。
  • 如果在两个列中添加值,其中一个值以文本形式表示 ("12"),而另一个值以数字形式表示 (12),DAX 会将字符串隐式转换为数字,然后执行加法并获得数值结果。 表达式 = "22" + 22 返回 44。
  • 如果你尝试连接两个数字,DAX 会将其表示为字符串并进行连接。 表达式 = 12 & 34 返回 "1234"。

隐式数据转换表

运算符通过在执行请求的运算之前强制转换所需的值来确定 DAX 执行的转换类型。 下表列出了运算符,以及当数据类型与相交单元格中的数据类型配对时 DAX 对它执行的转换。

注意

这些表不包括“文本”数据类型。 当数字以文本格式表示时,在某些情况下,Power BI 将尝试确定数字类型并将数据表示为数字。

加 (+)

INTEGER CURRENCY REAL 日期/时间
INTEGER INTEGER CURRENCY REAL 日期/时间
CURRENCY CURRENCY CURRENCY REAL 日期/时间
REAL REAL REAL REAL 日期/时间
日期/时间 日期/时间 日期/时间 日期/时间 日期/时间

例如,如果加法运算将实数与货币数据结合使用,DAX 会将这两个值转换为 REAL,并返回结果 REAL。

减法 (–)

下表中,行标题是被减数(左侧),列标题是减数(右侧)。

INTEGER CURRENCY REAL 日期/时间
INTEGER INTEGER CURRENCY REAL REAL
CURRENCY CURRENCY CURRENCY REAL REAL
REAL REAL REAL REAL REAL
日期/时间 日期/时间 日期/时间 日期/时间 日期/时间

例如,如果减法运算将日期与其他任何数据类型结合使用,DAX 会将两个值转换为日期,返回的值也是日期。

注意

数据模型支持一元运算符 -(负号),但此运算符不会更改操作数的数据类型。

乘 (*)

INTEGER CURRENCY REAL 日期/时间
INTEGER INTEGER CURRENCY REAL INTEGER
CURRENCY CURRENCY REAL CURRENCY CURRENCY
REAL REAL CURRENCY REAL REAL

例如,如果乘法运算将整数与实数结合使用,则 DAX 会将这两个数字转换成为实数,并且返回的值也是 REAL。

除 (/)

下表中,行标题是分子(左侧),列标题是分母(右侧)。

INTEGER CURRENCY REAL 日期/时间
INTEGER REAL CURRENCY REAL REAL
CURRENCY CURRENCY REAL CURRENCY REAL
REAL REAL REAL REAL REAL
日期/时间 REAL REAL REAL REAL

例如,如果除法运算将整数与货币值结合使用,则 DAX 会将这两个值转换为实数,并且结果也是实数。

比较运算符

在比较表达式中,DAX 会考虑布尔值大于字符串值,字符串值大于数值或日期/时间值。 数字和日期/时间值具有相同的排名。

DAX 不对布尔值或字符串值执行任何隐式转换。 根据另一个比较值的数据类型,BLANK 或空值转换为 0、"" 或 False。

下面的 DAX 表达式对此行为进行了说明:

  • =IF(FALSE()>"true","Expression is true", "Expression is false") 返回“表达式为 true”。

  • =IF("12">12,"Expression is true", "Expression is false") 返回“表达式为 true”。

  • =IF("12"=12,"Expression is true", "Expression is false") 返回“表达式为 false”。

DAX 对数字或日期/时间类型执行隐式转换,如下表所述:

比较
运算符
INTEGER CURRENCY REAL 日期/时间
INTEGER INTEGER CURRENCY REAL REAL
CURRENCY CURRENCY CURRENCY REAL REAL
REAL REAL REAL REAL REAL
日期/时间 REAL REAL REAL 日期/时间

空值、空字符串值和零值

DAX 以相同的新值类型 BLANK 表示 null、空值、空单元格或缺失值。 你可以使用 BLANK 函数创建空白,并使用 ISBLANK 函数对其进行测试。

诸如加法或串联之类的运算对空值的处理方式取决于单个函数。 下表总结了 DAX 和 Microsoft Excel 公式对空值的处理方式的区别。

表达式 DAX Excel
BLANK + BLANK BLANK 0(零)
BLANK + 5 5 5
BLANK * 5 BLANK 0(零)
5/BLANK 无穷大 Error
0/BLANK NaN Error
空白/空白 BLANK Error
FALSE OR BLANK FALSE FALSE
FALSE AND BLANK FALSE FALSE
TRUE OR BLANK TRUE TRUE
TRUE AND BLANK FALSE TRUE
BLANK OR BLANK BLANK Error
BLANK AND BLANK BLANK 错误

可以使用 Power BI Desktop 和数据执行各种操作。 有关 Power BI 功能的详细信息,请参阅以下资源: