PowerBI之DAX神功:第1卷第7回 基礎(chǔ)表函數(shù)之Filter函數(shù)
《孫興華講PowerBI火力全開》筆記 09.聚合函數(shù)與迭代函數(shù)? <2>迭代函數(shù)
講述了,AverageX、MaxX、MinX、CountX、CountaX、ProductX...它們與Filter函數(shù)一樣都是行上下文
語法:一張新表=Filter('表名', 篩選條件)
Filter函數(shù): 不僅是表函數(shù),還具有迭代功能(對(duì)表逐行掃描進(jìn)行篩選),說白了就是限制表的行數(shù)用的
Filter函數(shù)的作用就是:篩選表
例1:圖1-7-1如果我只想看男生的數(shù)據(jù),請(qǐng)你給我返回一張表

表 = FILTER('Sheet1','Sheet1'[性別]="男")

例2:如圖1-7-1我們想多條件篩選,現(xiàn)在要篩選一班的男生
表 = FILTER('Sheet1',AND('Sheet1'[性別]="男",'Sheet1'[班級(jí)]="一班"))
表 = FILTER('Sheet1','Sheet1'[性別]="男" && 'Sheet1'[班級(jí)]="一班")

例3:如圖1-7-1我們使用三個(gè)條件篩選,現(xiàn)在要篩選一班,男生,80分
表 = FILTER('Sheet1',AND(AND('Sheet1'[性別]="男",'Sheet1'[班級(jí)]="一班"),'Sheet1'[分?jǐn)?shù)]=80))
表 = FILTER('Sheet1','Sheet1'[性別]="男" && 'Sheet1'[班級(jí)]="一班" && 'Sheet1'[分?jǐn)?shù)]=80)

如果條件太多,這樣的代碼并不易讀:
現(xiàn)在,我們參照語法,將它寫成VAR形式:

一班男生 =?
var tb1 = FILTER('Sheet1','Sheet1'[性別]="男")
return
FILTER(tb1,'Sheet1'[班級(jí)]="一班")

一班男生80分 =?
var tb1 = FILTER('Sheet1','Sheet1'[性別]="男")
var tb2 =FILTER(tb1,'Sheet1'[班級(jí)]="一班")
return
FILTER(tb2,'Sheet1'[分?jǐn)?shù)]=80)

這個(gè)嵌套很好理解,邏輯與絕大多數(shù)編程相同
變量a = 1
變量b =?變量a + 1
變量c =?變量a + 變量b
現(xiàn)在變量c是什么?答:變量c=3

<Filter應(yīng)用> 做篩選條件、縮小表的范圍,節(jié)省時(shí)間,但是方法并不唯一,根據(jù)你的需求而定
例4:圖1-7-2 統(tǒng)計(jì)男生人數(shù)

假設(shè)這是100萬行數(shù)據(jù),我每行掃描一遍,發(fā)現(xiàn)是男生就記數(shù),這樣是不是很慢?
所以我們需要縮小計(jì)算范圍,既然是只統(tǒng)計(jì)男生人數(shù),那么我們篩選男生的表就可以了
男生人數(shù) = Calculate(Count([性別]) ,[性別]="男")
男生人數(shù) = Calculate(Count([性別]),FILTER('Sheet1','Sheet1'[性別]="男"))
男生人數(shù) = Countrows(FILTER('Sheet1','Sheet1'[性別]="男"))
三種寫法都可以,不要看過《The Definitive Guide to DAX》就跑出來抬扛,沒有什么是唯一寫法。

剛才我們都是操作一張表格,現(xiàn)在我們多張表操作


給通過英語四級(jí)的學(xué)生,英語平時(shí)成績(jī)+0.1分。
【先說新建列】
新成績(jī)1 = if(and(Related('學(xué)生表'[四級(jí)])="通過",'成績(jī)表'[學(xué)科]="英語"),'成績(jī)表'[平時(shí)成績(jī)]+0.1,BLANK())

新成績(jī)2 = CALCULATE(sumx('成績(jī)表',if(and(Related('學(xué)生表'[四級(jí)])="通過",'成績(jī)表'[學(xué)科]="英語"),'成績(jī)表'[平時(shí)成績(jī)]+0.1,BLANK())

但是,上面兩種方法都是在逐行掃描,判斷每一行是否符合條件,如果有100萬行,就要判斷100萬次,為了提升速度,我們可以將符合條件的人從表中篩選出來,對(duì)這張篩選后的表進(jìn)行計(jì)算。
新成績(jī)3 = CALCULATE(
var tb1=filter('成績(jī)表','成績(jī)表'[學(xué)科]="英語")
var tb2=filter(tb1,Related('學(xué)生表'[四級(jí)])="通過")
return
? ? ? ? sumx(tb2,'成績(jī)表'[平時(shí)成績(jī)]+0.1)
)

【再說度量值】
總分 = sum('成績(jī)表'[平時(shí)成績(jī)])
通過四級(jí)人員的成績(jī) = calculate(sum('成績(jī)表'[平時(shí)成績(jī)]),filter('學(xué)生表','學(xué)生表'[四級(jí)]="通過"))??
//這里不用關(guān)系函數(shù),filter的篩選條件在自己表中

今天的知識(shí)就講到這里,現(xiàn)在開始打臉
filter('學(xué)生表','學(xué)生表'[四級(jí)]="通過")? 是不是一張表?
那你為什么要問我《火力全開》第7節(jié)課:Calculate第二參數(shù)為什么可以是一張表?難到我第5課沒講嗎?
《孫興華講PowerBI火力全開》筆記07? 大家抬扛的地方
考生人數(shù)= Calculate(CountRows('學(xué)生表'), '成績(jī)表')?
Calculate第二參數(shù)可以是一張表你理解不?這節(jié)課我們就說到這里。
關(guān)于你們的第二個(gè)問題:為什么學(xué)生表是一端,成績(jī)表是多端,現(xiàn)在多端在篩選器上,而一端在計(jì)算器上。下節(jié)課咱們就打臉,我一次就講一件事。
關(guān)于Filter配合Calculate等更高級(jí)的應(yīng)用,我們按《The Definitive Guide to DAX》順序一點(diǎn)一點(diǎn)的講

注:《火力全開》是我自己通過經(jīng)驗(yàn)調(diào)整的學(xué)習(xí)順利,《DAX神功》(DAX原理)是按《The Definitive Guide to DAX》的順序講,講原理必會(huì)招來水軍的攻擊,為了防止他們組團(tuán)說我講的順序亂,所以我就按權(quán)威書籍的順序講,但是內(nèi)容肯定不一樣哦!
比如《線性代數(shù)》,權(quán)威書籍都是從行列式開始講的,其實(shí)我更建議從向量開始講,但是如果真的這么做了,肯定會(huì)招來爭(zhēng)議。于是我先講《火力全開》再講《DAX神功》,有了前面的鋪墊后,《DAX神功》就可以按《The Definitive Guide to DAX》的順序講了。
就跟有些人不讓我用中文變量和中文案例,說我使用中文太LOW了,我跟他們講道理是沒有用的,我只能讓他去看以下法律條文的規(guī)定,因?yàn)榉墒菣?quán)威:
《憲法》第4條第4款
《憲法》第19條第2款和第4款
《國(guó)家通用語言文字法》第一章 第4條