前述:
本次使用数据是包含产品表、客户表、区域表、销售订单表的一份销售订单数据,数据源链接如下:
链接:https://pan.baidu.com/s/1micl_09hFrgz2aUBERkeZg
提取码:y17e
一、CALCULATE
1.语法结构
语法结构 | CALCULATE(表达式,过滤条件1,过滤条件2……) |
参数设置 | 第一个参数必须有,一般为聚合函数表达式;过滤条件参数可有多个或不设置 |
返回值 | 返回值 |
2.用法介绍
(1)不设置筛选条件
订单数量 = CALCULATE(SUM('销售订单'[订单数量]))
没有设置筛选条件,和只用聚合函数计算效果一样
(2)设置筛选条件
例如我们要计算产品编号为1的订单数量:
产品1订单数量 = CALCULATE(SUM('销售订单'[订单数量]),'产品'[产品编号]=1)
由于我们设置了筛选条件是产品编号1,所以只计算了产品1的订单数量
二、FILTER
1.语法结构
语法结构 | FILTER(表、筛选条件) |
返回值 | 经过筛选的表 |
2.用法介绍
FILTER 不可单独使用,而是用于需要表作为参数的其他函数中:
(1)搭配CALCULATE
例如我们想要计算大于平均销售单价产品的订单数量:
大于平均单价订单数量 = CALCULATE(SUM('销售订单'[订单数量]),FILTER('销售订单','销售订单'[销售单价]>AVERAGE('销售订单'[销售单价])))
(2)搭配聚合函数、迭代函数
例如想要根据销售单价与订单数量计算客户编号为1的产品销售收入:
客户1的销售收入 = SUMX(FILTER('销售订单',[客户编号]=1),[订单数量]*[销售单价])
三、ALL
1.语法结构
语法结构 | ALL(要删除筛选器的表或列) |
返回值 | 返回已删除筛选器的表 |
2.用法介绍
(1)复制表
点击新建表——输入:
表名 = ALL(要复制的表)
(2)返回某一列为不重复表
点击新建表——输入:
表名 = ALL('表'[列])
(3)清除外部上下文筛选(重要)
新建以下两个度量值来观察对比:
订单数量 = SUM('销售订单'[订单数量])
总订单数量 = CALCULATE(SUM('销售订单'[订单数量]),ALL('产品'))
我们可以看到使用 ALL('产品')后度量值不会受到外部上下文的影响,每一行都会显示总订单数量,而不是像第一个度量值一样根据产品编号筛选,所以我们可以将其应用于类似于占比问题的计算中。
四、VALUES
1.语法结构
语法结构 | VALUES('表'[列]) |
返回值 | 返回该列不重复表 |
也就是说当某个函数需要的参数是表,但我们能提供的是列,则可以使用values函数进行转换
2.用法介绍
(1)返回某列不重复表(以事实表构建维度表)
例如当前模型中没有仓库编码这一单独的维度表,可以从销售订单表中提取出这个维度表:
新建表——输入:
仓库 = VALUES('销售订单'[仓库编码])
这个功能与前面的all函数第二个用法返回某一列为不重复表功能相同
(2)保持外部上下文筛选
这个功能与all函数清除外部上下文筛选功能相反,以all函数用法介绍(3)中构建的数据为例:
总订单数量 = CALCULATE(SUM('销售订单'[订单数量]),ALL('产品'))
接下来使用values恢复产品编号的筛选:
恢复筛选订单数量 = CALCULATE(SUM('销售订单'[订单数量]),ALL('产品'),VALUES('产品'[产品编号]))
(3)查找文本型数据
例如我们需要查找城区名称为Thames的邮编:
Thames邮编 = CALCULATE(VALUES('区域'[邮编]),'区域'[城区]="Thames")
有些朋友可能会疑惑values返回的是表,为什么在这里可以正常显示为一个值?
这是因为dax有一个重要特征:如果一个表只有一行一列,那么它也可以作为值来使用,但是如果没有被筛选为一行,是会报错的。
例如我们需要查找订单日期为2017年1月5日的产品编号:
产品编号查找 = CALCULATE(VALUES('销售订单'[产品编号]),'销售订单'[订单日期]=DATE(2017,1,5))
五、HASONEVALUE
1.语法结构
语法结构 | HASONEVALUE('表'[列]) |
返回值 | True/False,判断该列是否被过滤为仅有一个值,如果是一个值返回True,多个或无返回False |
2.用法介绍
一般作为IF函数第一个参数使用,来判断筛选后是否为一个值
补充:IF函数
IF(<logical_test>, <value_if_true>[, <value_if_false>])
术语 定义 logical_test 计算结果可以是 TRUE 或 FALSE 的任何值或表达式。 value_if_true 逻辑测试为 TRUE 时返回的值。 value_if_false (可选)逻辑测试为 FALSE 时返回的值。 如果省略,则返回 BLANK。
在values用法(3)中我们最后提到如果结果没有被筛选为一行,是会报错的,报错度量值如下所示:
产品编号查找 = CALCULATE(VALUES('销售订单'[产品编号]),'销售订单'[订单日期]=DATE(2017,1,5))
为了防止错误情况出现,我们可以借助于IF与HASONEVALUE进行错误拦截:
hasonevalue产品编号查找 = IF(HASONEVALUE('产品'[产品编号]),CALCULATE(VALUES('产品'[产品编号]),'销售订单'[订单日期]=DATE(2017,1,5)),"无")
红色部分来判断产品编号列是否被过滤为一个值,是的话返回橙色部分结果,不是的话返回蓝色结果