PowerBI之DAX神功:第1卷第8回 基礎(chǔ)表函數(shù)之ALL與ALLEXCEPT函數(shù)
這是我們上節(jié)課的兩個(gè)度量值公式:
通過四級(jí)人員的成績 = calculate(sum('成績表'[平時(shí)成績]),filter('學(xué)生表','學(xué)生表'[四級(jí)]="通過"))
考試學(xué)生有多少人= Calculate(CountRows('學(xué)生表'), '成績表')?
Calculate的篩選器可以用Filter,同時(shí)也可以使用一張表,因?yàn)镕ilter返回的就是一張表。ALL函數(shù)返回也是一張表,它也是表函數(shù),但是它與Filter相反。
Filter是篩選,ALL是全選
關(guān)于calculate第二參數(shù)篩選器,為什么可以是多端表,馬上打臉。
接下來,我們看這節(jié)課的知識(shí):這張表的表名是'Sheet1'

圖1-8-1,我想計(jì)算每個(gè)人的捐款占比,那我要先知道他們?nèi)齻€(gè)人一共捐了多少錢?

如圖1-8-2,張三10+李四20+王五30=總計(jì)60
想實(shí)現(xiàn)上表我們可以使用【新建列】
總捐款 = sum('Sheet1'[捐款])??
//新建列是行上下文無篩選功能
占比 = 'Sheet1'[捐款]/'Sheet1'[總捐款]?
現(xiàn)在多增加一個(gè)沒有用的列,無形當(dāng)中占用了內(nèi)存和硬盤
我們可以省略總捐款這個(gè)列寫成這樣
占比 = 'Sheet1'[捐款]/60

但是這個(gè)60是人算出來的,為了能將它寫活,我們新建【度量值】
固定值 = CALCULATE(sum([捐款]),all('Sheet1'))
在新建列中使用度量值:如圖1-8-3
占比 = 'Sheet1'[捐款]/[固定值]

為了更好的理解ALL(表),我們回到Excel中做這件事:

如圖1-8-4,我們想實(shí)現(xiàn)占比,就要算出三個(gè)人捐款總和,再用每個(gè)人的捐款金額除以捐款總和,我們在單元格操作時(shí),會(huì)用到絕對(duì)引用,保證除數(shù)是固定值。如圖1-8-5

$D$5這個(gè)單元格就是除數(shù)同時(shí)也是我們的度量值固定值:
固定值 = CALCULATE(sum([捐款]),all('Sheet1'))
ALL函數(shù)當(dāng)參數(shù)為表時(shí),它返回這張表中所有的行,就好比Excel中的絕對(duì)引用?,F(xiàn)在我們分析這個(gè)度量值:
【1】sum([捐款])是Calculate引擎中的計(jì)算器,它是一個(gè)吃飯用的碗,里面放著三個(gè)人捐款的錢。
【2】而all('Sheet1')是引擎中的篩選器,它代表這個(gè)表中的所有行,也就是說這張表中所有行的錢數(shù)總計(jì)是多少。
是不是與我們上節(jié)課講的Filter正好是相反的?
如果我們使用Filter('Sheet1','Sheet1'[性別]='男')做為篩選器,它只會(huì)從sum([捐款])這個(gè)度量值中拿出所有男生的捐款金額。而all('Sheet1')是拿所有人的。所以,我說Filter是篩選,ALL是全選。

接來下,我們嘗試在矩陣中實(shí)現(xiàn),分別建立3個(gè)度量值:圖1-8-6
總捐款=sum('Sheet1'[捐款])
固定值=CALCULATE([總捐款],all('Sheet1'))
占比 = [總捐款]/[固定值]

實(shí)際情況并不需要固定值這個(gè)度量值,我們目的是計(jì)算占比:
占比2 =?
VAR x = sum('Sheet1'[捐款])
VAR y= CALCULATE(sum('Sheet1'[捐款]),all('Sheet1'))?
return
? ? x/y


之前我們只有一張表,如果多張表,應(yīng)該考慮哪些問題呢?


雖然有5名學(xué)生,但是只有3人參與捐款,因?yàn)榫杩钍亲栽傅摹?/h1>我們使用這3個(gè)度量值:
總捐款 = sum('捐款表'[捐款])
固定值 = CALCULATE([總捐款],all('捐款表'))
占比 = [總捐款]/[固定值]

學(xué)號(hào)字段來自多端表:捐款表
現(xiàn)在打第1下臉:如圖1-8-7
有人提問:Calculate第二參數(shù)為什么不能是多端表?
我反問你:我要捐款表中的所有行,有問題嗎?
一端篩選多端我一直在矩陣上舉例與Calcaulate有什么關(guān)系?
大清亡了,跟關(guān)羽去世有關(guān)系嗎?關(guān)羽不是清朝的!
我們再啰嗦一遍CALCULATE
CALCULATE(計(jì)算器,篩選器)
計(jì)算器得到的是一個(gè)數(shù)字,我們從數(shù)字中提取滿足條件的那一部分,例如,計(jì)算器是男女生人數(shù)總和,篩選器篩選男生人數(shù)。就討論這件事與一端多端有什么聯(lián)系?沒聯(lián)系!

現(xiàn)在打第2下臉:將行標(biāo)題換成學(xué)生表中的姓名后就變成了這個(gè)樣子

【總捐款】這個(gè)度量值是對(duì)捐款表中捐款那一列的聚合,捐款表中沒有鄧七和趙六,所以這個(gè)度量值在篩選時(shí),不顯示鄧七和趙六的值。
【固定值】這個(gè)度量值,其實(shí)就是那個(gè)$D$5單元格,永恒不變的固定值。
當(dāng)我們將行標(biāo)題換成學(xué)生表中的姓名時(shí),鄧七和趙六就出現(xiàn)了,為什么?什么原理?姓名字段來自一端表:學(xué)生表,學(xué)生表中的姓名是學(xué)校全部的學(xué)生名單,趙六和鄧七雖然沒捐款,但是他們也是這個(gè)學(xué)校的學(xué)生,把他們捐款看成是0元,占比是0%,現(xiàn)在矩陣中顯示的是每個(gè)人占學(xué)??偩杩罱痤~的比例。
總結(jié):當(dāng)ALL(表名)的時(shí)候,無論是內(nèi)部篩選器還是外部篩選器,都被清除了。寫固定值時(shí),我們清除了篩選,所以它顯示永遠(yuǎn)120。外部篩選器,例如我們使用切片器,無論你使用多端表中的日期或班級(jí),還是一端表中的姓名,固定值120是永遠(yuǎn)不會(huì)變的。如圖1-8-9


ALL(表)并不是萬能的,例如現(xiàn)在這個(gè)問題:
為了更好的體現(xiàn)數(shù)據(jù),我們將矩陣中行標(biāo)題改成多端表中的【性別】字段,如圖1-8-10

如果你想分析,每個(gè)班男生和女生各占全??偩杩罱痤~的占比,就這么寫沒問題!
但是,如果你想分析,每個(gè)班男生和女生各占本班總捐款金額的占比,這么寫就不對(duì)了,因?yàn)橐话嗪投嗫偩杩罱痤~各60元。現(xiàn)在由于我們使用的是ALL(表),它返回一個(gè)固定的120不變。達(dá)不到我們的要求。
現(xiàn)在我們將度量值修改:
固定值 = CALCULATE([總捐款],all('捐款表'[性別]))
作用:只對(duì)【性別】取消篩選:如圖1-8-11

現(xiàn)在固定值仍然顯示120,沒錯(cuò)!因?yàn)槲覀兪褂昧?/strong>all('捐款表'[性別]),行標(biāo)題是性別篩選度量值時(shí),等同于ALL(表)返回一個(gè)固定值。
但是,當(dāng)我們將行標(biāo)題換成【班級(jí)】時(shí):如圖1-8-12

當(dāng)你將行標(biāo)題換成除了捐款表'[性別]以外任何字段時(shí),固定值都是可以篩選的。因?yàn)槲覀冎皇?span id="s0sssss00s" class="color-green-03">all('捐款表'[性別]),并沒有ALL整張表,只是性別這一個(gè)列清除了篩選,其它列可以正常篩選。
也就是說ALL(列)時(shí),只是那一列相當(dāng)于是ALL(表)的效果,返回固定值,其它列在篩選時(shí),等同于【總捐款】那個(gè)度量值,帶有篩選功能。

以上說的是內(nèi)部篩選器,接下來我們說外部篩選器:
固定值 = CALCULATE([總捐款],all('捐款表'[性別]))
固定值如上所示,我們使用性別做行標(biāo)題,固定值永久返回120

但是,當(dāng)我們使用班級(jí)做切片器時(shí),它可以讓固定值實(shí)現(xiàn)篩選功能,因?yàn)槲覀兊墓潭ㄖ抵皇?strong>all('捐款表'[性別]),如下圖

但是,當(dāng)我們將行標(biāo)題換成班級(jí)、切片器換成性別時(shí)
這是一道數(shù)學(xué)題:全校只有2個(gè)班捐款總計(jì)120元,一班和二班各捐款60元。因?yàn)槲覀兪褂玫氖?/span>all('捐款表'[性別]),所以班級(jí)做行標(biāo)題可以篩選固定值,每個(gè)班60元,但是外部切片器性別,就不能篩選固定值,因?yàn)?span id="s0sssss00s" class="color-default font-size-20">是all('捐款表'[性別])。

現(xiàn)在就驗(yàn)證了《火力全開》筆記第7課那句總結(jié):
當(dāng)ALL參數(shù)為列時(shí),忽略該列篩選,
但是,其它字段或外部篩選對(duì)其產(chǎn)生作用
這句話是語文知識(shí):其它字段或外部篩選。先讀前2個(gè)字,再讀后7個(gè)字。因?yàn)檫@句話,牽扯語文閱讀理解,ALL(列)也非常靈活,不易理解,不怪你們。

但是,接下來這就真的不應(yīng)該了
《火力全開》做了這樣一個(gè)總結(jié):
注意:ALL函數(shù)在引用列的時(shí)候,必需與矩陣的行和列在同一張表
假設(shè):
固定值 = CALCULATE([總捐款],all('捐款表'[學(xué)號(hào)]))
我使用捐款表中的學(xué)號(hào)做行標(biāo)題,現(xiàn)在固定值是120,這個(gè)你理解。

現(xiàn)在,我將學(xué)生表中的學(xué)號(hào)做行標(biāo)題,固定值變了,不再是120了

為什么?這是什么原理?哪有什么原理呀?
固定值?= CALCULATE([總捐款],all('捐款表'[學(xué)號(hào)]))
ALL函數(shù)的參數(shù)中是哪個(gè)表哪個(gè)列,不是用中文寫的嗎?你用其它表中的同名列,肯定無效呀。我現(xiàn)在舉一個(gè)行標(biāo)題的例子就足夠了。

我在《火力全開》中,分別用兩句話解釋ALL(表)與ALL(列)
你們?yōu)楹我欢ㄒ@自己?
ALL(表)?不管用什么篩選都返回一個(gè)固定值
ALL(列)? 只有用這個(gè)列篩選才返回一個(gè)固定值,其它列篩選都返回可以篩選的值,這時(shí)等效于計(jì)算器中的度量值。
就這么簡單的一個(gè)事,不要往復(fù)雜里搞!

回歸正題,現(xiàn)在我們只寫了一列
你可以寫多列 All(表名[列名1],表名[列名2],表名[列名3],…….)
假設(shè)有100個(gè)列,你想在ALL里面寫99個(gè)列,這樣顯然不方便,我們使用另一個(gè)函數(shù)
Allexcept函數(shù):除…之外
語法:Allexcept(表名,表名[列名])? ? ? ?
等同于? ?All(表名[列名1],表名[列名2],表名[列名3],…….)

網(wǎng)友問:我應(yīng)該什么時(shí)候用ALL(表)?什么時(shí)候用ALL(列)?
答:需要用ALL(表)時(shí)用ALL(表),需要用ALL(列)時(shí)用ALL(列),這個(gè)由你的業(yè)務(wù)決定,看你要做什么樣的分析。
關(guān)于ALL函數(shù)與Calculate函數(shù)配合使用的詳細(xì)講解,
我會(huì)安排在《DAX神功》第1卷末來講,
現(xiàn)在您需要知道ALL函數(shù)是怎么回事
關(guān)于它的具體用法不用著急,我們慢慢來
