在“ DAX权威指南”中,对Allexcept函数进行了完全相同的描述:
“您还可以指定一个完整的表,而不是指定扩展表一部分的所有列”(P430)
和dax.guide上的
“ ALLEXCEPT会从Sales的扩展版本中删除过滤器,其中包括从Sales开始可以通过多对一关系访问的所有表。” https://www.sqlbi.com/articles/managing-all-functions-in-dax-all-allselected-allnoblankrow-allexcept/
它们都暗示Allexcept不用作Calculate作为过滤器参数的顶级函数时返回表,就像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] ) )
)
)
请解释“错误版本”行为不符合预期的确切原因。
答案 0 :(得分:1)
有趣的问题。我不是专家,但我会尝试一下。 首先,据我了解,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] ) )
上进行计算的表格。
在写答案时,我已经意识到,这并不是您要求的确切原因,因此我深表歉意。
答案 1 :(得分:0)
我做了很多测试,以找出Allexcept()的确切行为,这是我的结论:
Allexcept()具有两种不同的行为,就像All():
1。作为“ removefilter”,它从列中删除所有未从扩展表中排除的过滤器,但它本身不返回任何内容;
2。返回一个“特殊”扩展表,其中仅包含未从原始扩展表中排除的那些列。在这种情况下,结果表在可能的情况下仍会像扩展表一样工作。
行为1太清楚了,无法解释。要激活此行为,只需将allexcept()用作Calculate()或Calculatetble()的顶级函数作为过滤器参数。
行为2的证明和理解要复杂得多。
此公式证明Allexcept()可以返回表并且结果表不完整(强烈建议使用DAXStudio测试结果):
EVALUATE
GENERATE (
VALUES ( Data[Name] ),
CALCULATETABLE ( ALLEXCEPT ( Data, Data[Name] ) )
)
这表明Allexcept()可以在需要时自行返回表:
EVALUATE
GENERATE ( VALUES ( Data[Name] ), ALLEXCEPT ( Data, Data[Name] ) )
这显示出Allexcept()返回的结果表是扩展的结果表:
EVALUATE
CALCULATETABLE ( 'Date', CALCULATETABLE ( ALLEXCEPT ( Data, Data[Name],Data[Datetime],Data[Type] ) ) )
最后一个公式显示,当用作表返回者时,Allexcept()会忽略原始扩展表上的任何过滤器参数,这包括排除的列和未排除的列,这意味着原始扩展的所有过滤器桌子没用:
CALCULATETABLE (
'Date',
CALCULATETABLE (
ALLEXCEPT ( Data, Data[Name] ),
Data[Name] = "Tom",
'Date'[YearMonth] ="2018-1-1"
)
)
如果有任何建议,请发表评论!