数据类型
DAX 可以使用七种常用的数据类型进行计算。在下面的列表中,我们展示了同一种数据类型在 DAX 种的名称和它更常见的名称。例如,布尔值(Boolean values)在 DAX 术语中被称为 TRUE/FALSE。我们更愿意遵循事实上的命名标准,将它们称为布尔值。除此之外,还有两种比较特殊的类型会在最后介绍
- 整数 (Integer)
- 十进制数 (Float)
- 货币 (Currency), 内部存储为整数的固定小数
- 日期 (DateTime)
- 布尔值 (TRUE/FALSE)
- 文本 (String)
- 二进制 (Binary)
- Blank/Null 类型
- 变体(Variant) 类型
DAX 数据类型在不同工具中使用的名称
DAX 有一个强大的类型处理系统,因此你不必担心数据类型:当你编写 DAX 表达式时,结果的类型基于表达式使用的术语类型自动调整。我们称之为隐式转换,但在某些情况下,它不会进行转换。 例如,如果 DAX 函数需要日期数据类型,而你的列的数据类型为文本,DAX 函数将不能正常工作。 因此,获取适用于列的正确数据类型是重要并且有用的,如果 DAX 表达式返回的类型不是预期的类型,你需要须检查表达式使用的术语的数据类型。
例如,如果某列的数据类型是日期,那么求和的结果也是日期;然而,如果对整数使用相同的TRUNC 函数来删除小数部分。
Power BI 还提供另外两种数据类型:日期类型和时间类型。在引擎内部,它们是日期/时间的简单变体。实际上,两种类型分别只存储日期/时间的整数部分或小数部分。
闰年错误
1983 年发布的流行电子表格程序 Lotus 1-2-3 在处理 DateTime 数据类型时出现了一个错误。它认为 1900 年是闰年,尽管事实并非如此(一个世纪的最后一年是闰年,前提是前两位数字除以 4 没有余数)。当时,Excel 第一版的开发团队故意复制了这个 bug,以保持与 Lotus 1-2-3 的兼容性。从那以后,出于兼容性考虑,Excel 的每一个新版本都把这个 bug 作为一个特性来维护。
为了保持与 Excel 的向后兼容,目前这个 bug 仍然在 DAX 中。Bug 的存在(或者我们应该称之为特性吗?)可能会导致 1900 年 3 月 1 日之前出现错误。因此,根据设计,DAX 的第一个官方支持的日期是 1900 年 3 月 1 日。在此日期之前执行的日期计算可能会导致错误,应该被认为是不准确的。
DAX 中的 1 代表 1899 年 12 月 31 日,而 EXCEL 是 1900 年 1 月 1 日,存在这种差别的原因是 Lotus 1-2-3 的最初版本有一个 bug,认为 1900 是一个闰年,其中包括 1900 年 2 月 29 日。实际上 1900 年不是闰年,所以在 1900 年 3 月 2 日之前的日期在 Lotus 1-2-3 中被误写了。由于莲花的电子表格在当时非常受欢迎,为了与其竞争,微软在自家的 EXCEL 上继承了这个 bug 以便用户可以无缝切换。DAX 的开发者对这个 Bug 采用了另一种不同的实现方式,导致在这个特定的时间段内,DAX 与 Excel 存在 1 天的差距。
如果你需要在 1900 年之前进行计算,你应该使用数学方法来将其移动到 1900 年之后的日期,执行计算,然后再平移回去。
布尔值(TRUE/FALSE)
布尔数据类型用于表示逻辑条件。例如,由以下表达式定义的计算列类型为布尔型:
- = Sales[Unit Price] > Sales[Unit Cost]
复制代码
你也可以将布尔数据类型视为数字,其中 TRUE=1 和 FALSE=0。这在排序时很有用,因为 TRUE >FALSE。相反的,如果在逻辑判断中直接使用数字,那么 0 将会被视为 FALSE,例如下面的表达式始终返回空
文本(String)
DAX 中的每个字符串都存储为 16 位 Unicode 字符串。默认情况下,字符串之间的比较是不区分大小写的,因此这两个字符串“PowerPivot”和“POWERPIVOT”是相等的。
PowerQuery 比较字符串时默认区分大小写,这是两者的一个不同点,需特别留意。如果你使用的是 Analysis Services 表格模型,可以自行设置是否区分大小写
二进制(Binary)
二进制数据类型用于在数据模型中存储图像,在 DAX 中无法访问该数据类型。它主要被 Power View 或其他客户端工具用来显示直接存储在数据模型中的图片。在 Power BI 等其他工具中可能无法使用
在圣经第一版中此处使用的格式类型是二进制大对象(BLOB)
空白/Null 类型
BLANK 不对应 SQL 中的 NULL。DAX 中的 BLANK 不遵循 NULL 在 SQL 中的计算逻辑。在中间结果可能是 BLANK 的表达式中,必须注意这种区别。 你可以使用 BLANK 函数创建空白,并使用 ISBLANK 对其进行测试。
关于空白、空字符串和零值的处理:
表达式 | DAX | Excel | BLANK + BLANK | BLANK | 0(零) | BLANK + 5 | 5 | 5 | BLANK * 5 | BLANK | 0(零) | 5/BLANK | 无穷大 | 错误 | 0/BLANK | NaN | 错误 | 空白/空白 | BLANK | 错误 | FALSE OR BLANK | FALSE | FALSE | FALSE AND BLANK | FALSE | FALSE | TRUE OR BLANK | TRUE | TRUE | TRUE AND BLANK | FALSE | TRUE | BLANK OR BLANK | BLANK | 错误 | BLANK AND BLANK | BLANK | 错误 |
关于 BLANK 的更多注意事项,请在阅读BLANK 的函数介绍。
变体/Variant 类型
变体数据类型用于可能返回不同数据类型的度量值,具体取决于度量值使用的条件表达式。例如,下面的语句可以返回整数或字符串,所以它返回一个变体类型:
- IF ( [measure] > 0, 1, "N/A" )
复制代码计算列不能返回变体类型,否则会收到提示:“不能使用生成变量数据类型的表达式定义计算列”。变体适用于 DAX 度量值,或更一般的说,DAX 表达式
DAX 运算符
了解了运算符在确定表达式类型的重要性之后,我们通过下表来看一下 DAX 中的运算符列表。
运算符列表
参数类型 | 符号 | 用法 | 举例 | 小括号 | ( ) | 改变计算优先级和分组 | (5+2)*3 | 四则运算 | + | 相加 | 4 + 2 | | − | 相减/逻辑否 | 5 − 3 | | * | 相乘 | 4 * 2 | | / | 相除 | 4 / 2 | 比较符号 | = | 等于 | [CountryRegion] = “USA” | | <> | 不等于 | [CountryRegion] <> “USA” | | > | 大于 | [Quantity] > 0 | | >= | 大于或等于 | [Quantity] >= 100 | | < | 小于 | [Quantity] < 0 | | <= | 小于或等于 | [Quantity] <= 100 | | == | 严格相等 | Product[Color] == BLANK() | 文本连接 | & | 连接符 | “Value is” & [Amount] | 逻辑判断 | && | 两个布尔表达式之间的逻辑“与” | [CountryRegion] = “USA” && [Quantity]>0 | | || | 两个布尔表达式之间的逻辑“或” | [CountryRegion] = “USA” || [Quantity] > 0 | | IN | 元素包含在列表中 | [CountryRegion] IN {“USA”, “Canada”} | | NOT | 否定判断 | NOT [Quantity] > 0 |
注意:IN 运算符 2016 年 11 月发布,可能无法在 Excel 2016 以及更早的版本中使用,详情参考IN 和 CONTAINSROW一文。
此外,逻辑运算符也可以作为 DAX 函数使用,语法非常类似于 Excel。例如,你可以这样写:
- AND ( [CountryRegion] = "USA", [Quantity] > 0 )
- OR ( [CountryRegion] = "USA", [Quantity] > 0 )
复制代码
它们分别与下面的写法等价:
- [CountryRegion] = "USA" && [Quantity] > 0
- [CountryRegion] = "USA" || [Quantity] > 0
复制代码
当你必须编写复杂条件时,使用函数代替运算符进行布尔逻辑运算变得非常有用。事实上,当需要格式化大量代码时,函数比运算符更容易格式化和读取。然而,函数的主要缺点是一次只能传入两个参数。如果需要计算两个以上的条件,就需要嵌套函数。
严格相等运算
当两个参数的值相同或都为空时,操作符==返回 TRUE,此运算符不执行字符串和数字之间的任何隐式转换,也就是说,将空值(BLANK)与任何其他值比较,比如 0、空字符串等,都将返回 FALSE。
只有当两个术语中至少有一个为空、空字符串或 0 时,==运算才与=不同。以下是使用“严格等于”运算符的有效表达式:
- Product[Color] == "Red"
- Product[Color] == BLANK() -- Product[Color] 为 BLANK 时返回 TRUE, 为 "" 或其他值时返回 FALSE
- Product[Color] == "" -- Product[Color] 为空字符串时返回 TRUE, 为 BLANK 或其他值时返回 FALSE
- Sales[Quantity] == 1
- Sales[Quantity] == BLANK() -- Sales[Quantity] 为 BLANK 时返回 TRUE, 为 "" 或其他值时返回 FALSE
- Sales[Quantity] == 0 -- Sales[Quantity] 为 0 时返回 TRUE, 为 BLANK 或其他值时返回 FALSE
复制代码
严格相等运算(==)在 Power BI, Azure Analysis Services, and Analysis Services 2019 中可用,但不支持早期的 Analysis Services 和 Power Pivot for Excel.
扩展阅读:
Power BI 中的数据类型
理解 DAX 中的数值类型转换 |