Power BI之DAX神功:第2卷第10回 初步理解時間智能計算過程
一、什么是時間智能
有些問題,你在搜索引擎查詢時,答案會收錄百科中,也會有很多專業(yè)的回答和總結(jié),哪怕是搜索:什么是人。 都可以得到專業(yè)答案。
但是,當你輸入:什么是時間智能
我保證,你只能搜到賣課的廣告或者是幫助賣課人推廣的廣告。
他們大多給你一個這樣的答案:時間段、始發(fā)站終點站、平移、平移間隔、重組時間段等等(無論字數(shù)長短,最終離不開這個圈)
你冷靜的想一想,微軟官方和《The Definitive Guide to DAX》都沒有給你總結(jié),證明它需要的不是“總結(jié)”!
二、創(chuàng)建日期表為什么避開CALENDARAUTO函數(shù)
《孫興華講PowerBI火力全開》第28課 動態(tài)日期表
日期表 = ADDCOLUMNS(?
CALENDAR(FIRSTDATE('表名'[日期列]),LASTDATE('表名'[日期列])),
"年", YEAR ( [Date] ),
"季度", ROUNDUP(MONTH([Date])/3,0),
"月", MONTH([Date]),
"周", weeknum([Date]),
"年季度", year([date]) & "Q" & ROUNDUP(MONTH([Date])/3,0),
"年月", year([Date]) * 100 + MONTH([Date]),
"年周", year([Date]) * 100 + weeknum([Date]),
"星期幾", WEEKDAY([Date])?
)

關(guān)于,CALENDARAUTO函數(shù)我個人不建議你使用,他從所有表中找所有日期列(不包含計算列),并不是從指定列中去找。
我舉一個簡單的例子:假如我做人力工作,我用上面的公式生成一張日期表,分析入職和離職情況:


我使用CALENDAR可以從指定表入職時間和離職時間中找到最小日期和最大日期生成一張日期表。
但是,使用CALENDARAUTO函數(shù)時:

它直接生成了1980年1月1日至2021年12月31日,因為它將員工生日也算進去了,且從開始日期所在年第一天至結(jié)束日期所在年最后一天生成日期表。
三、多個日期表的使用
建議使用《DAX神功》第1卷第21回 Calculate調(diào)節(jié)器USERELATIONSHIP函數(shù)
不建議你使用兩個日期表分別與多端表建議一對多關(guān)系,這會給后期處理造成很大的麻煩。
四、理解基礎(chǔ)時間智能計算
大多數(shù)網(wǎng)友看書看到這里就蒙了,別蒙!這里的知識很簡單!前提是《DAX神功》你順序的看過來,沒有跳集。
只要你理解了 《DAX神功》第2卷第3回 計算移動平均值再次理解Filter+ALL 這節(jié)課就夠了

【新建表】
日期表 = ADDCOLUMNS(
CALENDAR(FIRSTDATE('Sheet1'[日期]),LASTDATE('Sheet1'[日期])),
"年", YEAR ( [Date] ),
"季度", ROUNDUP(MONTH([Date])/3,0),
"月", MONTH([Date]),
"周", weeknum([Date]),
"年季度", year([date]) & "Q" & ROUNDUP(MONTH([Date])/3,0),
"年月", year([Date]) * 100 + MONTH([Date]),
"年周", year([Date]) * 100 + weeknum([Date]),
"星期幾", WEEKDAY([Date])
)

度量值1 = CALCULATE([總銷售],FILTER('日期表', '日期表'[Date]>=date(2021,1,1) && '日期表'[Date]<=date(2021,12,31)))
// 度量值1:篩選出2021/1/1~2021/12/31之間的銷售,因為Filter使用的是表,所以可以篩選
度量值2 = CALCULATE([總銷售],FILTER(all('日期表'), '日期表'[Date]>=date(2021,1,1) && '日期表'[Date]<=date(2021,12,31)))
// 度量值2:在度量值1的基礎(chǔ)上使用了all(表),最終得到2021/1/1~2021/12/31總銷量之和,一個固定的值。
度量值3 = calculate([總銷售],FILTER(all('日期表'),'日期表'[Date]<=max('日期表'[Date]) && '日期表'[年]=2021))
// 度量值3:在《DAX神功》第2卷第3回講移動平均時介紹過他可以實現(xiàn)累積。本案例得到2021年月累積。
度量值4 = calculate([總銷售],FILTER(all('日期表'[Date]),'日期表'[Date]<=max('日期表'[Date]) && year('日期表'[Date])=2021))
// 度量值4:度量值3限制日期表所有列,而度量值4限制日期表[Date]列,在本案例上效果是相同的。在《DAX神功》第2卷第3回也詳細介紹過二者的應(yīng)用環(huán)境。得到2021年月累積。

以上只是利用平移的方式,讓你理解時間智能計算的過程,后續(xù)使用時間智能函數(shù)會簡單很多
五、回答網(wǎng)友問題
關(guān)于《The Definitive Guide to DAX》中有一個類似的度量值:
度量值5 =?
? ? CALCULATE(
? ? ? ? CALCULATE(
? ? ? ? ? ? [總銷售],
? ? ? ? ? ? '日期表'[Date]>=date(2021,1,1) && '日期表'[Date]<=date(2021,12,31),
? ? ? ? ? ? all('日期表')
? ? ? ? ),
? ? ? ? '日期表'[年]=2021
? ? )
這就是我常說的,不要輕易說人家對或錯!
書中只是想講一個道理,舉出這樣一個案例。
事實上你用不到這樣的寫法:
《DAX神功》第1卷第18回 孫興華說:Calculate計值順序和其它DAX函數(shù)一樣,是從內(nèi)向外的。內(nèi)層已經(jīng)指定了從2021/1/1至2021/12/31,為何還要在外層篩選2021年?
書中要表達的意思是:度量值3和度量值4算的是每個月的累積是通過平移的方法計算的,現(xiàn)在如果算指定年和指定月份區(qū)間求累積,你用平移的方法實現(xiàn)起來就不容易了,但是后面要講的時間智能日期函數(shù)就非常簡單了。這就是賣課人常說的,取新的范圍:

六、網(wǎng)友對Calculate計值順序的爭議
因為剛剛提到了Calculate計值順序,所以這里就再說一下。
聲明:我從不證明誰對誰錯!我只是證明路不只一條?。ㄓ袪幾h的內(nèi)容我可以擺出來讓大家自己去鑒定,但從不下結(jié)論)
例如,一個國家花錢買裝備要比研發(fā)裝備省錢,但是為什么還要研發(fā)裝備?這個道理大家都懂。數(shù)據(jù)分析,并不能從網(wǎng)上照搬案例,有一些程序員都可能從某些社區(qū)通過搜索,查到一些現(xiàn)成代碼進行修改,但是分析不行,你的分析和人家的不一樣,如果通過"借鑒"書籍或國外文獻就能搞定,那可能不需要學(xué)習DAX,Excel工作表函數(shù)一定可以搞定,也許還更簡單。
例如,有網(wǎng)友提出這樣問題

網(wǎng)友提問時,文字說明:


我在《DAX神功》第1卷第18回,并沒有說《The Definitive Guide to DAX》中說的不對,而是白紙黑字跟大家講,路不只一條,我們思路不同,就好比去一個地方,路線不同,但是終點一樣。
如同:有些人說編程英語比邏輯重要,其實誰重要都無所謂,能把代碼寫出來,正確運行才是王道。
關(guān)于我提出的,所有DAX函數(shù)都是從內(nèi)向外計值順序,我舉證:以下圖為例

VAR x='Sheet1'[Name]? ? //指當前行的Name字段值
從內(nèi)向外,先看內(nèi)層,內(nèi)層Calculate指的是A,B,C,D,E每個Name的Score值,新建列逐行迭代將ABCDE對應(yīng)的值寫在每一行。(如果A有2行,第1次出現(xiàn)時Score是73,第2次是1,那A對應(yīng)的值都是74)
內(nèi)層已經(jīng)完成了每個值的分配任務(wù),外層再寫all(表)對我度量值本身無影響。
證明:
如果公式寫成: Calculate(sum('Sheet1'[Score]),all(表)) // 返回ABCDE所有Name的Score值總和(一個固定值)
Calculate第一參數(shù),是對[Score]列的聚合。
可是,我們現(xiàn)在的度量值,外層的Calculate第一參數(shù)生成新的列,你并沒有對新列進行重新聚合。

換句話說,你并沒有將 ?新列中的 ?73+97+55+99+59 ?sum在一起,關(guān)于score這列的聚合,內(nèi)層calculate已經(jīng)完成了他的使命,將值分配給每個Name了,這個時候再all(表)已經(jīng)無意義了,因為篩選完畢了,結(jié)果生成了,再去取消表的篩選不會影響這個度量值。
無論是《The Definitive Guide to DAX》提出的從外向內(nèi),還是我提出的從內(nèi)向外,最終我們結(jié)果是一致的。
其實,你細品,從外向內(nèi)的說法,外層all(表),內(nèi)層篩選這張表,當然原理是重新篩選,但是說出來同樣很牽強。

在接下來的幾節(jié)課中,我們將開始時間智能日期函數(shù)之旅!

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