[已解决] 关于TreatAs函数正确的使用方式

  [复制链接]
查看115610 | 回复122 | 2021-2-19 01:06:53 | 显示全部楼层 |阅读模式
TreatAs的官方解释是,将表表达式的结果作为筛选器应用于无关表中的列。

本示例中,已取消维度表“日期”与事实表“订单”之间的关系,并编写了三个度量值。

1、销售额_All,想通过All来取消日期的筛选上下文(2011年至2014年4年的销售额),奇怪的是实际返回的还是有筛选上下文(等同销售额),最奇怪的是总计却是正确的;
2、销售额_All_VAR,想通过VAR来方便阅读,但无论行标签还是总计,返回的都等同销售额。

以上,还请各位大佬指点:

1、如何才能取消筛选上下文?
2、此处的VAR,是错在哪里?

谢谢。 11213112038081.png
11213112038084.zip (564.43 KB, 下载次数: 0)
回复

使用道具 举报

db7382 | 2021-2-19 01:14:53 | 显示全部楼层
你是不是对蓝框里16117xxx那个值是怎么来的感到奇怪?其实等会看完一些基本原理后,你一定会说:哦,就是这样呀,没什么好奇怪的。

针对这个度量值,你先回答几个基本的问题,后面会用的上。
  1. 销售额_All =

  2. CALCULATE(

  3. [销售额],

  4. ALL('日期'[日期])

  5. )
复制代码


1. 这里的ALL('日期'[日期])作用是什么?它得到的结果是什么?
2. 总计行的蓝框所在位置的计值上下文(EVALUVATION CONTEXT, EC)是什么?
(我声明一下:不是我愿意这样半中半英的说话,是因为我从学DAX第一天开始就是看的英文的材料,很多术语的中文翻译我不太确定;国内成体系的中文材料几乎没有)


参考答案:
1. 作为CALCULATE/CALCULATETABLE()所使用的filter modifier,ALL('日期'[日期])移除了'日期'[日期]上的所有筛选,即201401<='日期'[日期]<=201412的筛选在后续的计算中被无视,相当于'日期'[日期]没有任何筛选。这既是ALL('日期'[日期])在此的作用,又是结果。
对于ALLX一族(ALL, ALLEXCEPT, ALLSELECTED等)函数的深入解析可参考:
https://www.sqlbi.com/articles/managing-all-functions-in-dax-all-allselected-allnoblankrow-allexcept/

2. 这里首先可以肯定是没有行上下文了(ROW CONTEXT, RC);要看来自外部(FILTERS PANE里未隐藏的筛选、本页面里的切片器、来自其他VIZ)的筛选上下文(FILTER CONTEXT, FC),直接点这里就行:
11213112038082.png
我再多啰嗦一句,这个“总计”其实和上面分列的每一行半毛钱关系没有,它的计算根本就不是去把这些行总的计起来;它在自己的一亩三分地里(你标记的蓝色框所在的EC中)自己玩。(地区[国家]列是特意加进来当背景板说明外部筛选情况的,影响不到计算的结果,因为所有数据对应的国家都是中国)

这个时候再次把度量值进一步还原:
  1. 销售额_All =

  2. CALCULATE ( //1

  3.   CALCULATE ( //2
复制代码
结合上面那几个基本问题,我想你应该也明白得七七八八了吧。我们一起理一下:
1. CALCULATE 1先把蓝框的EC都全部转化成FC,2014/1/1<='日期'[日期]<=2014/12/31;
2. CALCULATE 1里的ALL('日期'[日期])把1里的筛选又移除了;落得白茫茫一片大地真干净,CALCULATE 2省事了;
3. CALCULATE 2里TREATAS()建立虚拟关系,用VALUES ( '日期'[日期] )的结果筛选'订单'[订单日期]。刚才2里就说了,'日期'[日期]上的筛选已被移除,VALUES ( '日期'[日期] )就应该是这一列所有不重复值了(如果不放心,可以另外用度量值CALCULATE( COUNTROWS( VALUES('日期'[日期]) ), ALL( '日期'[日期] ) )验证一下),筛选完'订单'[订单日期]后一累加,就是最后结果了。

其实没什么特别的,就是这样了。其他的度量值分析也大同小异。

既然说到这里了,我就在提一句建议,被引用的度量值,计量不要再含CALCULATE/CALCULATETABLE,因为多一次出现,就意味着多一次上下文转换,即又增加了复杂度,DEBUG的难度也随之增加一层。生活已经不易,就不要再给自己添麻烦了。。。
回复

使用道具 举报

小斌斌 | 2021-2-19 01:19:53 | 显示全部楼层
把变量结果用在CALCULATE的第一参数,这时候有必要再重新学一下DAX
回复

使用道具 举报

se11989009 | 2021-2-19 01:25:53 | 显示全部楼层
把变量结果用在CALCULATE的第一参数,这时候有必要再重新学一下DAX


一语中的,受教了
回复

使用道具 举报

quike111 | 2021-2-19 01:29:54 | 显示全部楼层
你是不是对蓝框里16117xxx那个值是怎么来的感到奇怪?其实等会看完一些基本原理后,你一定会说:哦,就是这 ...


非常专业,膜拜一下。

又尝试写了两个度量值,去年和YTD的销售额,但返回的值还是不对。

小弟愚钝,还望大佬再次指点。

谢谢。
回复

使用道具 举报

万一 | 2021-2-19 01:31:54 | 显示全部楼层
补上附件,请大佬赐教。 11213112038083.png
11213112038085.zip (564 KB, 下载次数: 0)
回复

使用道具 举报

qeen | 2021-2-19 01:38:54 | 显示全部楼层
补上附件,请大佬赐教。


时间智能函数,需要标记日期表
回复

使用道具 举报

力仔 | 2021-2-19 01:43:54 | 显示全部楼层
补上附件,请大佬赐教。


销售额_LY全部为空的原因很简单,日期在多重筛选后,结果为空。

虽然你用DATEADD('日期'[日期],-1,YEAR)取得了前一年的日期区间,但是你不能忽略,用作行标签的'日期'[年月]的筛选还是存在,很明显这两个筛选叠加后的结果就是空。

你可以直接在度量值里把'日期'[年月]的筛选移除,应该就是你希望的结果了。
  1. 销售额_LY =

  2. CALCULATE ( [销售额], DATEADD ( '日期'[日期], -1, YEAR ), ALL ( '日期'[年月] ) )
复制代码


YTD那个度量值修改方法也一样。
回复

使用道具 举报

fuxinxia | 2021-2-19 01:50:54 | 显示全部楼层
销售额_LY全部为空的原因很简单,日期在多重筛选后,结果为空。

虽然你用DATEADD('日期'[日期],-1,YEA ...


一题可以多解,受教了。
回复

使用道具 举报

powerfive | 2021-6-20 12:44:37 | 显示全部楼层
小白一个 顶一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则