一、构建图表原则
1、任何图表都需要有时间维度,否则图表无意义(此案例没有设置时间维度,佐罗老师失误了。)
2、图表两个要素:1、元素(非运算字段、列、度量值);2、度量值;如果没有,就用DAX生成;
3、为制作图表,会用DAX生成新表,生成新表(table)不与 base table 建立联系,而是通过 TREATAS 函数建立联系,原因:不让新表污染原数据模型。
二、需要解决的问题清单
1、X轴为变量,变量分别为省份、行业、职业和产品四类,它们分属于不同的维度表,如何将这四类维元素整合到一起? (佐罗老师:构建ABC 元素表 )
对于没有的表、列、度量值,有且只有一条路可以走,用DAX做出来。
问题一:如何将省份、行业、职业和产品四类元素整合到一起?
答案: 把四个元素从不同的表中提出来,合成一张表。
问题二:如何提出来和合成新表?
需要用到4个函数: ADDCOLUMNS 、SELECTCOLUMNS、DISTINCT和 UNION 四个函数。
以下是这4个函数的功能:
1、DISTINCT(ColumnNameorTableExpr) 针对一个列参数,返回由一列组成的一个表,列中包含不同(唯一)值。或针对一个表表达式参数,返回包含不同(唯一)值组合的多个列。
参数 ColumnNameorTableExpr 列名或表的表达式 参数性质:必填项
2、ADDCOLUMNS( table , name , expression ) 返回具有 DAX 表达式指定的新列的表。
参数 table :The table to which new columns to be add 参数性质:必填项 不可重复
参数 name : the name of new colunms to be add 参数性质:必填项 可重复
参数 expression : the expression for the new columns to be add 参数性质:必填项 可重复
例如: ADDCOlLUMNS( '客户表 ,"相貌" , "美丽" ) 在客户表中增加“相貌”列,新增列以“美丽”文本填充。
3、SELECTCOLUMNS() 返回具有从表中选择的列以及 DAX 表达式指定的新列的表。
参数 table :The table from which columns are selected 参数性质:必填项 不可重复
参数 name : the name of new colunms to be add 参数性质:必填项 可重复
参数 expression : the expression for the new columns to be add 参数性质:必填项 可重复
4、UNION(Table , ……)返回其列相匹配的两个表格的联合。
参数 table : a table that will participate in the union 参数性质:必填项 可重复
构建客户职业表(其他表可以复制后,改变参数):
第一步 VAR 客户职业 = DISTINCT ( '客户表'[ 职业] ) // 找出客户有什么不同的职业 ,返回只有一个列的表。
第二步 VAR 客户职业 = ADDCOLUMNS( DISTINCT ( '客户表'[职业] ), "元素类型" , "客户职业" )
// 在 distint 返回表中,增加一列名为"元素类型" ,内容"客户职业", "客户职业"为表达式,如果再增加列,也依照"元素类型" , "客户职业"样式增加,为可复用。
第三步 VAR 客户职业 = SELECTCOLUMNS( ADDCOLUMNS(
DISTINCT ( '客户表'[职业] ),
"元素类型" ,
"客户职业" ),
"元素名称" , [职业] ,
// 对ADDCOLUMNS返回的表 选取列 职业列 取名 “元素名称” [职业]为表达式,
"元素类型" , [元素类型] // 对ADDCOLUMNS返回的表选取列元素类型 取名 “元素类型”[元素类型]为表达式 ,此行为第二参数和第三参数的复用
)
问题三:如何计算累计百分比?如何根据不同的类别正确累计百分比?
累计百分比= 不同类别的销售额 / 总销售额 * 100%
分解: 1、总销售额 :即无论外部环境上下文如何变化, 销售额不受影响,是一个绝对常量,首先想到ALL ()函数或是 REMOVEFILTERS()函数,清除环境上下文的筛选;
DAX : 总销售额 = CALCULATE( sum('订单[销售额]) , ALL( 'ABC 元素表 ))
2、累计销售额 :累计销售额,一定是一个迭加的过程,需要用到迭加函数,到底是哪个函数?
如果没有看到答案,我很难想到是用FILTER函数筛选而迭加!FILTER函数的第二参数为 Expression ,运用度量值进行筛选符合条件元素名称,再进行加计汇总。 迭代函数的神奇之处就是会在表内的每一行数据都会筛选一遍,找到符合条件的行而形成子集,进行计算。遗憾的是我的脑力实在不够,所以,只能就答案来解答案:
VAR totalsale = CALCULATE ('sum ( '订单[销售额] ) , ALL('ABC 元素表) )
// 计算销售额的绝对值 ,用ALL函数做CALCULATE的筛选器时,清除环境上下文的影响,进行全集运算。
VAR currentevalue = sum( '订单[销售额] )
// 指定视图层(环境上下文)某一类别的销售额,就是当前行的销售额。
VAR cumulativevalue = CALCULATE( sum( '订单[销售额] ) , FILTER( 'ABC 元素表 , sum( '订单[销售额] ) >= currentevalue ) )
// 这个是最难想的点:运用FILTER筛选器的迭加功能,在每一个当前值的位置上,通过ABC 元素表中每一个类别都进行一次筛选,寻找表中每一行的销售额>=当前行的销售额的行,将这些行筛选为一张表(计算的子集),再按CALCULATE函数的第一参数进行运算。
RETERN DIVIDE (cumulativevalue , totalsale )
// 返回累计占总额的百分比。
未完待续…………