PowerBI之DAX神功:第1卷第15回 在筛选上下文中使用DISTINCT和SUMMARIZE
《The Definitive Guide to DAX 》使用了较大篇幅在讲这节课,我又蒙圈了,但是当我使用逻辑读书时发现跟用眼睛读书结果不同。其实问题原本很简单:
《DAX神功》第1卷第9回基础表函数之VALUES与DISTINCT函数和空行
一、DISTINCT函数
DISTINCT(表[列]):返回去重后的单列表
【新建表】新表=DISTINCT(表[性别])

DISTINCT(表):所有列都重复才去重并返回去重后的表。
【新建表】新表=DISTINCT(表)

例题:以下销售记录中客户的年龄均值,当客户在同一年龄有多次购买时,只当成一次购物

《The Definitive Guide to DAX 》中先是使用DISTINCT('Sheet1'[年龄])获得一张对年龄去重后的表,告诉你这是错误的
我相信,只要听懂了DISTINCT函数的人都知道这是错误的。
【新建表】新表=DISTINCT('Sheet1'[年龄])

这就是业务问题,我一直跟大家强调,一道题就好比领导交给你的工作,你自己必须先会做,计算机只是帮你计算。
例如:张三每天放9999个屁,365天之后,他一共放了多少个屁?
9999*365 或者 10000*365-365 这是你的逻辑, 它的结果是可以借助工具计算。
当我们看到题目之后,就应该很清楚,我们需要的是:

这是多列去重的问题,无论我们使用DISTINCT或者Values都是做不到的,《DAX神功》第1卷第9回我们留下了多列去重的悬念。那如何可以做到多列去重呢?
二、为什么我讲SUMMARIZE函数一带而过?
前不久,有位粉丝朋友问我,为什么你所有的PowerBI课程中对SUMMARIZE函数都是一带而过?貌似它很重要吧?我为了简化大家学习压力,所以全程使用SUMMARIZECOLUMNS代替《火力全开》笔记23.分组与连接函数,接下来我们对比一下它们的区别:
《1》单列去重后返回表
【新建表】新表 = DISTINCT('Sheet1'[年龄])
【新建表】新表 = VALUES('Sheet1'[年龄])
【新建表】新表 = SUMMARIZE('Sheet1','Sheet1'[年龄])
【新建表】新表 = SummarizeColumns('Sheet1'[年龄])

《2》多列去重后返回表,顺序向后写列名就可以了
新表 = SUMMARIZE('Sheet1','Sheet1'[姓名],'Sheet1'[年龄])
新表 = SummarizeColumns('Sheet1'[姓名],'Sheet1'[年龄])

关于排序问题你不用在意,我们正在做的是数据分析,不是打印
《3》分组聚合
新表 = SUMMARIZE('Sheet1','Sheet1'[姓名],'Sheet1'[年龄],"合计",sum(Sheet1[年龄]))
新表 = SummarizeColumns('Sheet1'[姓名],'Sheet1'[年龄],"合计",sum(Sheet1[年龄]))

《4》子类别小计与总计,不常用
新表 = SUMMARIZE('Sheet1',ROLLUP('Sheet1'[姓名],'Sheet1'[年龄]),"合计",sum(Sheet1[年龄]))
新表 = SUMMARIZE('Sheet1',ROLLUPGROUP('Sheet1'[姓名],'Sheet1'[年龄]),"合计",sum(Sheet1[年龄]))

《5》只显示总计,不常用
新表 = SUMMARIZE('Sheet1',ROLLUP(ROLLUPGROUP('Sheet1'[姓名],'Sheet1'[年龄])),"合计",sum(Sheet1[年龄]))

SUMMARIZECOLUMNS也有类似功能:ROLLUPGROUP和ROLLUPADDISSUBTOTAL,等我们精讲SUMMARIZECOLUMNS时再说。
为什么说子类别小计与总计不常用?现在是数据分析,我们不是打印表格,这么干,就是将自己继续分析的路给堵死了。
《6》如果我们需要获得下面这张表

我们可以先通过:
【新建表】新表 = SUMMARIZE('Sheet1','Sheet1'[姓名],'Sheet1'[年龄])

再通过新建列:这是错的,因为得到的合计是新表中的年龄之和,并不是Sheet1表中的
错!【新建列】合计=calculate(sum('新表'[年龄]),all('新表'))

正确!【新建列】合计 = calculate(sum('Sheet1'[年龄]),all('Sheet1'))

但是,我们有简便的写法,将上面这两步,合并在一个公式中
简化:《火力全开》26.人工造表最终方案 ADDCOLUMNS 从指定的表开始添加列
新表 = ADDCOLUMNS(SUMMARIZE('Sheet1','Sheet1'[姓名],'Sheet1'[年龄]),"合计",sum(Sheet1[年龄]))
新表 = ADDCOLUMNS(SummarizeColumns('Sheet1'[姓名],'Sheet1'[年龄]),"合计",sum(Sheet1[年龄]))

而且从速度上讲,SummarizeColumns优于ADDCOLUMNS+SUMMARIZE优于SUMMARIZE现在,知道我为什么对 SUMMARIZE一带而过了吗?
但是,SUMMARIZECOLUMNS并不完美,它不支持上下文转换时发生的计算,所以绝大部分度量值中不能使用,如果需要在度量值中执行分组和新建列时用SUMMARIZE+ADDCOLUMNS,那是不是这样呢?我们来验证一下:
三、回到本课一开始的例题上来

方法一: SummarizeColumns
<1>【新建表】新表 = SummarizeColumns('Sheet1'[姓名],'Sheet1'[年龄])

<2> 【度量值】平均年龄1=average('新表'[年龄])

由于度量值与Sheet1并没有关系,所以Sheet1表中的字段是无法筛选这个度量值的。

方法二:Summarize
平均年龄2 =
VAR tb = Summarize('Sheet1','Sheet1'[姓名],'Sheet1'[年龄])
return
averagex(tb,'Sheet1'[年龄])

现在我们来验证一下,SummarizeColumns不能用在大多数度量值中:
平均年龄3 =
VAR tb = SummarizeColumns('Sheet1'[姓名],'Sheet1'[年龄])
return
averagex(tb,'Sheet1'[年龄])

可以显示,但是不能筛选,你将任何字段放到行标题中,都会显示该视觉对象无法显示
PS:这节课的重点并不是SUMMARIZECOLUMNS,后面我们会有单独的课程详细讲解SUMMARIZECOLUMNS。你要知道,如果不用Summarize,我们也可以用SUMMARIZECOLUMNS分步完成度量值,但是在其它方面,SUMMARIZECOLUMNS都优于Summarize。
