首页 > 解决方案 > Allexcept() 函数在扩展表中究竟返回什么?为什么?

问题描述

Allexcept 函数在“DAX 权威指南”中的描述完全相同:

“您还可以指定一个完整的表,而不是作为扩展表一部分的表的所有列”(P430)

在 dax.guide 上:

“ALLEXCEPT 从 Sales 的扩展版本中删除了过滤器,其中包括可以通过从 Sales 开始的多对一关系访问的所有表。” https://www.sqlbi.com/articles/managing-all-functions-in-dax-all-allselected-allnoblankrow-allexcept/

它们都暗示 Allexcept 在不用作计算中的顶级函数时返回一个表作为过滤器参数,就像 All() 所做的一样,而在我的实践中它是不同的:

考虑一个单表模型,例如:

Name    Datetime
John    2018/6/25
James   2018/7/7
Smith   2018/7/27
Smith   2018/11/21
Smith   2018/6/9
Mary    2019/1/31
Emily   2018/8/20
John    2018/6/9
Mary    2018/11/11
John    2018/8/21

使用带有计算列的 Calendarauto() 使用相关日历:

YearMonth = FORMAT('Date'[Date],"yyyymm")

现在想知道每个Name对应多少个YearMonth,应该是这样的:

Name MonthNum
John    2
James   1
Smith   3
Mary    2
Emily   1

了解扩展表和 Allexcept(以及上下文转换的工作原理)后,我使用了如下公式:

Wrong = 
ADDCOLUMNS (
    VALUES ( Data[Name] ),
    "MonthNum", CALCULATE (
            DISTINCTCOUNT ( 'Date'[YearMonth] ),
            CALCULATETABLE ( ALLEXCEPT ( Data, Data[Name] ) )
        )
    )

结果是:

Name    MonthNum
John    5
James   5
Smith   5
Mary    5
Emily   5

但我知道如何通过在Calculatetable之后添加“数据”来使其正确:

  Correct = 
ADDCOLUMNS (
    VALUES ( Data[Name] ),
    "MonthNum", CALCULATE (
            DISTINCTCOUNT ( 'Date'[YearMonth] ),
            CALCULATETABLE ( Data, ALLEXCEPT ( Data, Data[Name] ) )
        )
    )

请解释错误版本未按预期运行的确切原因。

标签: powerbidax

解决方案


有趣的问题。我不是 dax 专家,但我会尝试一下。首先,据我了解,ALL,ALLSELECTED... 自己不返回任何内容,它们只是清除过滤器。不确定,如果它是相关的,但可能值得一提。

为什么错误的列不起作用?这与关系有很大关系。如果您只是连接数据和日历表,它会创建从日历到数据表的单向关系。

如果将其更改为双向关系(仅出于科学目的),即使“错误”的列公式也将起作用,因为引擎可以保持名称过滤器处于活动状态。

现在让我们看看为什么正确的一个有效,但另一个在您的情况下失败。让我们首先隔离计算表。

正确的 -correct_calc = CALCULATETABLE ( Sheet1, ALLEXCEPT ( Sheet1, Sheet1[Name] ) )

返回

正确计算表

虽然错了 -wrong_calc = CALCULATETABLE ( ALLEXCEPT ( Sheet1, Sheet1[Name] ) )

返回

计算表错误

考虑到这些表,我猜想正确的一个保留“名称”过滤器,因为它们存在于计算表中,因此引擎只看到每个“名称”表的一部分。

另一方面,错误的只是保留所有日期,而不考虑“名称”过滤器,因为根本不考虑“名称”值,因为VALUES ( Data[Name] )您正在计算的表和表之间没有关系,即CALCULATETABLE ( ALLEXCEPT ( Data, Data[Name] ) ).

在写答案时,我意识到,这不是你要求的确切原因,所以我很抱歉。


推荐阅读