从数据到信息
从信息到洞察

EVALUATE

DAX 是一门编程语言也是一门查询语言

初识 EVALUATE

DAX 查询使用返回表的 DAX 表达式,与 EVALUATE 语句联用。完整的 DAX 查询语法示例如下:

[DEFINE { MEASURE <tableName>[<name>] = <expression> }]
EVALUATE <table>
[ORDER BY {<expression> [{ASC | DESC}]} [, ...]
[START AT {<value>|<parameter>} [, ...]] ]

初始的 DEFINE MEASURE 定义了用于本地查询度量值(也就是说,它们存在于当前查询的生命周期中)。当调试公式时,它会非常有用,因为你可以定义一个局部变量,测试它,一旦它可以按照预期的行为运行,就把它放到模型中。稍后你将看到关于这种语法的更多示例。

查询语法主要由可选参数组成,最简单的查询是从现有表中检索所有列和行:

EVALUATE Product

产品表的查询结果

ORDER BY 字句

如果要控制结果的排序规则,可以使用 ORDER BY 字句

EVALUATE Product 
ORDER BY Product[Color],
Product[Brand] ASC,
Product[Class] DESC
在模型中定义的 “按列排序” 属性在 DAX 查询中没有效果。即使你可以通过按列排序属性查询单个列来查看排序数据, 你也不必依赖于此行为, 就像你不能依赖 SQL 查询中的聚集索引一样。生成动态 DAX 查询的客户端应读取模型元数据中的 “按列排序” 属性, 然后按条件生成相应的排序。在 DAX 和 SQL 中,必须始终使用通过显式 ORDER BY 排序的数据作为结果。

ASC 和 DESC 关键词

ASC 和 DESC 关键字是可选的;如果未声明, 则默认情使用 ASC。你可以在下图 中看到上一查询的结果, 其中数据按颜色、品牌和类别进行排序。

产品表查询结果,品牌和颜色按升序排列,类别按降序排列

START AT 关键词

START AT 条件也是可选的,只能与 ORDER BY 子句结合使用。你可以在 ORDER BY 语句中为每个列指定起始值。在无状态应用程序中,START AT 条件对于分页非常有用,这些应用程序只从查询中获取有限数量的行,然后在用户请求下一页数据时发送另一个查询。例如,查看以下查询:

EVALUATE Product
ORDER BY Product[Color],
Product[Brand] ASC,
Product[Class] DESC
START AT
"Yellow", "Tailspin Toys"

查询返回如图所示的表格,其中只包含从”Yellow”、 “Tailspin Toys”开始的行

对已排序的产品表的查询结果从 Yellow、Tailspin Toys 的组合开始

请注意,从哪里起始这个概念取决于 ORDER BY 子句中指定的顺序方向。如果 Product[Brand]被指定为 DESC,如下例所示,结果中将不包括 Wide World Importers,而其他品牌,如 Southridge Video 和 Northwind Trader,会在 Tailspin Toys 后显示。

EVALUATE Product
ORDER BY Product[Color],
Product[Brand] DESC,
Product[Class] DESC
START AT
"Yellow", "Tailspin Toys"

产品表按品牌降序,查询结果将从 Yellow ,Tailspin Toys brand 的组合开始

若要筛选行并更改 DAX 查询返回的列, 必须在 EVALUATE 关键字后使用一些特定的表函数处理表表达式。

深入了解 EVALUATE

EVALUATE 是用于计算和物化表的 DAX 声明,考虑到 DEFINE MEASURE 对调试公式很有用,接下来会详细解释,因为通常你会将表函数用作度量值中使用的标量表达式的筛选器参数,但是在 SQL Server Management Studio 和 DAX Studio 等环境中测试它们要容易得多,在这些环境中,你可以编写返回表的查询。

介绍 DEFINE MEASURE

[DEFINE { MEASURE <tableName>[<name>] = <expression> }]
EVALUATE <table>

你可以使用 EVALUATE 语句定义一个或多个度量值,如下面的示例所示:

DEFINE
    MEASURE Sales[Quantity] =
        SUM ( Sales[Quantity] )
    MEASURE Sales[Total Cost] =
        SUMX (
            Sales,
            Sales[Quantity] * Sales[Unit Cost]
        )
EVALUATE
ADDCOLUMNS (
    VALUES ( Product[Brand] ),
    "Quantity", [Quantity],
    "Cost", [Total Cost]
)

使用此语句,你必须将度量值与表名相关联*,如果使用表中已存在的名称,在行上下文不存在时,将在 EVALUATE 中重写原表达式。例如,前面的示例将用同名度量值覆盖表的 Quantity 列。你在结果的每一行中看到的值是为每个品牌聚合所有行的 Quantity 列的总和。

*实际上,除了这种情况之外,不建议在度量值前加表名

通常,在查询中重写已有名称不是一个好主意。尽管如此,当你希望将数据模型中定义的度量值替换为查询使用的临时定义时(通常是出于调试或优化的原因),这是非常有用的。例如,假设你有一个查询,如下所示,其中度量值 Discounted Sales 不能得到正确结果:

EVALUATE
ADDCOLUMNS (
    VALUES ( Product[Brand] ),
    "Discounted Sales", [Discounted Sales]
)

你可以创建具有相同名称的本地度量值,并对其进行修改和测试,直到计值正确为止,然后才在数据模型中复制更正后的度量值:

DEFINE
    MEASURE Sales[Discounted Sales] =
        SUMX (
            Sales,
            Sales[Quantity] * ( Sales[Unit Price] - Sales[Unit Discount] )
        )
EVALUATE
ADDCOLUMNS (
    VALUES ( Product[Brand] ),
    "Discounted Sales", [Discounted Sales]
)

在查询中重写数据模型的度量值不会影响数据模型的其他代码中对该度量值的现有引用。例如,考虑以下两个数据模型中的度量值:

[Total Sales] :=
SUMX (
    Sales,
    Sales[Quantity] * Sales[Net Price]
)
[Average Price] :=
[Total Sales] / SUM ( Sales[Quantity] )

如果在查询中重写了 Total Sales,你将看到它不会影响 Average Price 的计算,如下面的示例所示:

DEFINE
    MEASURE Sales[Total Sales] = 0
EVALUATE
ADDCOLUMNS (
    VALUES ( Product[Brand] ),
    "Total Sales", [Total Sales],
    "Average Price", [Average Price]
)

Average Price 在数据模型中计值,使用 Total Sales 的原生定义而不是在本地查询中的临时定义。

在 EVALUATE 中使用 VAR

你可以在 EVALUATE 语句中使用一种与标准语法略有不同的方式定义变量,通常使用的语法是:

VAR
<variableName> = <expression>
RETURN
<expressionConsumingVariable>

RETURN 之后的表达式可以访问前面定义的变量。这种语法可以替换 DAX 中的任何标量或表表达式。但是,当你编写 EVALUATE 语句时,你也可以在 DEFINE 的部分定义变量,而不必在之后编写 RETURN:

DEFINE
    VAR ExpensiveProducts =
        FILTER (
            Product,
            Product[Unit Price] > 3000
        )
EVALUATE
CALCULATETABLE (
    Product,
    ExpensiveProducts
)

一个更完整的 EVALUATE 语法定义如下:

[DEFINE
[{ MEASURE <tableName>[<name>] = <expression> }]
[{ VAR <variableName> = <expression> }]
]
EVALUATE <table>

在任何情况下,只有在 EVALUATE 后的表达式中使用该变量时,才会对该变量计值,并且变量的计算环境不依赖于在定义变量后发生的筛选上下文操作。换句话说,你也可以使用 VAR/Return 语法,如以下示例所示:

EVALUATE
VAR ExpensiveProducts =
    FILTER (
        Product,
        Product[Unit Price] > 3000
    )
RETURN
    CALCULATETABLE (
        Product,
        ExpensiveProducts
    )

 

4
说点什么

avatar
1000
 
鼓掌微笑开心憧憬爱你色并不觉得吃瓜doge二哈喵喵思考笑哭捂脸悲伤大哭抓狂汗偷笑打脸捂眼黑线问号晕拜拜闭嘴衰咒骂ok作揖
2 评论数
2 被回复的评论
2 订阅评论的人数
 
查看最近回复
查看最热评论
  订阅本文评论  
最新 最旧 得票最多
提醒
大力丸
成员
大力丸

高老师:定义变量VAR后面的名称不支持中文的吗

Rainman1124
成员
Rainman1124

高老师:
文中:START AT条件也是可选的,只能与ORDER BY子句结合使用。你可以在ORDER BY语句中为每个列指定起始值。
这里是不是应该是:你可以在START AT语句中为每个列指定起始值。