PowerBI之DAX神功:第1卷第15回 在篩選上下文中使用DISTINCT和SUMMARIZE
《The Definitive Guide to DAX 》使用了較大篇幅在講這節(jié)課,我又蒙圈了,但是當我使用邏輯讀書時發(fā)現(xiàn)跟用眼睛讀書結果不同。其實問題原本很簡單:
《DAX神功》第1卷第9回基礎表函數(shù)之VALUES與DISTINCT函數(shù)和空行
一、DISTINCT函數(shù)
DISTINCT(表[列]):返回去重后的單列表
【新建表】新表=DISTINCT(表[性別])

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

例題:以下銷售記錄中客戶的年齡均值,當客戶在同一年齡有多次購買時,只當成一次購物

《The Definitive Guide to DAX 》中先是使用DISTINCT('Sheet1'[年齡])獲得一張對年齡去重后的表,告訴你這是錯誤的
我相信,只要聽懂了DISTINCT函數(shù)的人都知道這是錯誤的。
【新建表】新表=DISTINCT('Sheet1'[年齡])

這就是業(yè)務問題,我一直跟大家強調(diào),一道題就好比領導交給你的工作,你自己必須先會做,計算機只是幫你計算。
例如:張三每天放9999個屁,365天之后,他一共放了多少個屁?
9999*365? ?或者? 10000*365-365? 這是你的邏輯,? 它的結果是可以借助工具計算。
當我們看到題目之后,就應該很清楚,我們需要的是:

這是多列去重的問題,無論我們使用DISTINCT或者Values都是做不到的,《DAX神功》第1卷第9回我們留下了多列去重的懸念。那如何可以做到多列去重呢?
二、為什么我講SUMMARIZE函數(shù)一帶而過?
前不久,有位粉絲朋友問我,為什么你所有的PowerBI課程中對SUMMARIZE函數(shù)都是一帶而過?貌似它很重要吧?我為了簡化大家學習壓力,所以全程使用SUMMARIZECOLUMNS代替《火力全開》筆記23.分組與連接函數(shù),接下來我們對比一下它們的區(qū)別:
《1》單列去重后返回表
【新建表】新表 = DISTINCT('Sheet1'[年齡])
【新建表】新表 = VALUES('Sheet1'[年齡])
【新建表】新表 = SUMMARIZE('Sheet1','Sheet1'[年齡])
【新建表】新表 = SummarizeColumns('Sheet1'[年齡])

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

關于排序問題你不用在意,我們正在做的是數(shù)據(jù)分析,不是打印
《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時再說。
為什么說子類別小計與總計不常用?現(xiàn)在是數(shù)據(jù)分析,我們不是打印表格,這么干,就是將自己繼續(xù)分析的路給堵死了。
《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優(yōu)于ADDCOLUMNS+SUMMARIZE優(yōu)于SUMMARIZE現(xiàn)在,知道我為什么對 SUMMARIZE一帶而過了嗎?
但是,SUMMARIZECOLUMNS并不完美,它不支持上下文轉(zhuǎn)換時發(fā)生的計算,所以絕大部分度量值中不能使用,如果需要在度量值中執(zhí)行分組和新建列時用SUMMARIZE+ADDCOLUMNS,那是不是這樣呢?我們來驗證一下:
三、回到本課一開始的例題上來

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

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

由于度量值與Sheet1并沒有關系,所以Sheet1表中的字段是無法篩選這個度量值的。

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

現(xiàn)在我們來驗證一下,SummarizeColumns不能用在大多數(shù)度量值中:
平均年齡3 =?
VAR tb = SummarizeColumns('Sheet1'[姓名],'Sheet1'[年齡])
return
averagex(tb,'Sheet1'[年齡])

可以顯示,但是不能篩選,你將任何字段放到行標題中,都會顯示該視覺對象無法顯示
PS:這節(jié)課的重點并不是SUMMARIZECOLUMNS,后面我們會有單獨的課程詳細講解SUMMARIZECOLUMNS。你要知道,如果不用Summarize,我們也可以用SUMMARIZECOLUMNS分步完成度量值,但是在其它方面,SUMMARIZECOLUMNS都優(yōu)于Summarize。
