Power BI之DAX神功:第4卷第3回 計(jì)算列創(chuàng)建關(guān)系中的循環(huán)依賴
民間有句俗語:
天堂有路你不走,地獄無門你自來。
--意為自討苦吃,不懂變通
用這句話來形容今天要講的知識(shí),太恰當(dāng)了!
一、前景回顧

上節(jié)課一定有人會(huì)說,序號(hào)直接就可以獲取:
但是,你將兩張表通過序號(hào)建立關(guān)系時(shí),提示循環(huán)依賴:

上節(jié)課我用Switch的方法成功避坑!當(dāng)然原理我要講,可是我上節(jié)課要先講如何避坑。然后我再證明DAX原理在很多情況下他是化簡(jiǎn)為繁:)
你明知有人一小時(shí)后即將來打你,你不選擇報(bào)警,而選擇準(zhǔn)備武器跟他打仗,那就是互毆。你能用Switch避開,你就是不用,你用DAX原理,就要付出沉痛的代價(jià)。
上節(jié)課,我是在建立關(guān)系后使用這個(gè)公式,我不需要講原理,學(xué)到這個(gè)階段都看得懂這個(gè)公式,但是現(xiàn)在我沒有建立關(guān)系,使用了這個(gè)公式,我就講清楚原理。
二、Filter憑什么可以無關(guān)系篩選?
明確的告訴你:Filter本身是無法做到無關(guān)系篩選的。那為什么上面的公式做到了呢?

在兩張表無關(guān)系的情況下使用新建表:
返回結(jié)果:肯定是找不到客戶表中的指定列

但是在新建列里面就可以了

你先回答我一個(gè)問題,我對(duì)客戶表做新建列,是不是在客戶表里面的操作,那我在filter中指定的'客戶表'[消費(fèi)金額]是不是指當(dāng)前行消費(fèi)金額?就這么簡(jiǎn)單。如果你說不是這樣的,那我證明給你看:
是不是當(dāng)前行的會(huì)員卡號(hào)與當(dāng)前行的姓名連接:

那為什么我通過這種方法新建的序號(hào)列不能與區(qū)間表序號(hào)列建立關(guān)系呢?
三、單循環(huán)依賴
兩個(gè)表連線為什么會(huì)出現(xiàn)循環(huán)依賴呢,權(quán)威指南的解釋:Values檢測(cè)空行,而Distinct不檢測(cè)空行。讓我們將Values改成Distinct。原理:詳見《DAX神功》第1卷第9回
我們這個(gè)案例沒有空行,只是DAX在設(shè)計(jì)之初考慮到了這個(gè)問題,擔(dān)心你以后可能會(huì)通過Values產(chǎn)生空行,造成已經(jīng)連線的關(guān)系出錯(cuò),干脆就不讓你直接使用可能產(chǎn)生空行的函數(shù)。
舉個(gè)例子:我現(xiàn)在要招聘一個(gè)政治老師,兩個(gè)應(yīng)聘者:張三和李四,筆試和試講二者都在伯仲之間,但是張三英語比美國(guó)新聞主持人還厲害,我承認(rèn)張三是個(gè)很強(qiáng)的人,但是我這里廟小,張三應(yīng)該有更大的發(fā)展空間,所以我為了安全起見,我選擇李四。(當(dāng)然如果招聘英語老師我肯定選張三)
一定會(huì)有小伙伴說,你不是說過滿足實(shí)時(shí)參照完整性的表,就可以避開原理嗎?現(xiàn)在又用上原理了,怎么解釋呀?我剛剛在上面說過了:你能用Switch避開,你就是不用,你用DAX原理,就要付出沉痛的代價(jià):)
現(xiàn)在就可以連線了:

四、Calculate中避免使用布爾篩選器
上面我們提到了VALUES檢測(cè)空值,DISTINCT不檢測(cè)空值,同理,ALL檢測(cè)空值,ALLNOBLANKROW忽略空值。
假設(shè)上一個(gè)公式return后面寫成
Calculate([度量值],'表[列]'="篩選條件")
因?yàn)樗牡葍r(jià)公式:這個(gè)知識(shí)點(diǎn)在之前的課程中至少提到了10次以上
Calculate([度量值],filter(ALL('表[列]'),'表[列]'="篩選條件"))
ALL就是檢測(cè)空行,ALLNOBLANKROW不檢測(cè)空行,所以你必須寫成
五、雙循環(huán)依賴
有些小伙伴又要問了,如果客戶表是下面這樣,有重復(fù),我們需要先聚合再判斷

《DAX神功》第1卷第20回 循環(huán)依賴什么鬼?我們講過原例
當(dāng)我用客戶表新建列的序號(hào)列與區(qū)間表序號(hào)列建立關(guān)系時(shí),我們假設(shè)關(guān)系建立成功了,他們就是一對(duì)多關(guān)系,多端表的擴(kuò)展表包含一端表所有列。(這是擴(kuò)展表原理)

一對(duì)多關(guān)系,一端表(區(qū)間表)的序號(hào)可以篩選多端表(客戶表)的序號(hào)(新增列),但是多端表(客戶表)的序號(hào)因?yàn)槭切猩舷挛?,它在生成時(shí)還被自己表其它3列進(jìn)行篩選。這又是循環(huán)依賴。詳見《DAX神功》第1卷第20回 循環(huán)依賴什么鬼?
所以你不能將度量值寫成:
要寫成:原理《DAX神功》第1卷第20回 講過了不再重復(fù)
然后我們重新寫客戶表中的序號(hào)列公式:
這樣就可以了,你不知不覺中處理了兩次循環(huán)依賴,這就是DAX原理

六、SELECTEDVALUE內(nèi)有隱藏Values
《DAX神功》第2卷第19回?我們講到了什么情況下,使用SELECTEDVALUE函數(shù)代替IF+HASONEVALUE組合
IF(HASONEVALUE(字段名), VALUES(字段名),否則返回什么)
等價(jià)
SELECTEDVALUE(字段名,否則返回什么)
一旦你使用了SELECTEDVALUE默認(rèn)內(nèi)部嵌套了VALUES,又出現(xiàn)了檢測(cè)空行的問題,這時(shí)你必須使用:?IF(HASONEVALUE(字段名),?DISTINCT(字段名),否則返回什么)
七、總結(jié)
如果你相信我,用了《DAX神功》第1卷第20回 循環(huán)依賴什么鬼?講的方法,也就是上節(jié)課SWITCH避坑,VALUES、ALL、SELECTEDVALUE....就全部避開了。

《孫興華講PowerBI火力全開》PowerBI必學(xué)課程
https://www.bilibili.com/video/BV1qa4y1H7wp
《DAX神功》文字版合集:
https://www.bilibili.com/read/readlist/rl442274
《DAX神功》視頻版合集:
https://www.bilibili.com/video/BV1YE411E7p3
《DAX神功番外篇》文字版合集:
https://www.bilibili.com/read/readlist/rl478271
PowerBI(DAX函數(shù))、PowerQuery(M函數(shù))、Python辦公自動(dòng)化、Python爬蟲、Python數(shù)據(jù)分析、ExcelVBA、WordVBA、AccessVBA、MySQL等等