Power BI之DAX神功:答網(wǎng)友問(wèn)07 什么是改變計(jì)算顆粒度
一、網(wǎng)友提問(wèn)
問(wèn):我在看某權(quán)威書(shū)籍中,學(xué)到改變計(jì)算顆粒度,沒(méi)看懂不知道怎么用?
答:如果有一天,你回到公元2000年,對(duì)著大家說(shuō)“奧力給”他們肯定不知道是什么意思。如果你回到唐朝,跟他們說(shuō)哈蘇、萊卡、索尼大法,人們同樣聽(tīng)不懂。不要在文字上研究,它是一個(gè)時(shí)代的產(chǎn)物,只是一個(gè)名字。
二、我們先看一個(gè)案例

我們想將休息日的信息Vlookup到日期表:
Excel工作表函數(shù)、M函數(shù)、VBA、Pandas等等都可以實(shí)現(xiàn)
但是,現(xiàn)在我們講的是DAX原理,我們就用DAX方式
【新建列】工作日 = if(ISBLANK(LOOKUPVALUE('休息日'[休息日],'休息日'[休息日],'日期表'[日期])),1,0)
語(yǔ)法詳見(jiàn)《孫興華講PowerBI火力全開(kāi)》第2課 建模與關(guān)系函數(shù)

【度量值】總銷售 = sum('銷售表'[銷售])?
【度量值】總天數(shù) = COUNTROWS('日期表')? ? //共15天
【度量值】工作日天數(shù) = sum('日期表'[工作日])? ?//共11天,因?yàn)橛?天是休息日
【度量值】這期間的平均值 = DIVIDE([總銷售],[工作日天數(shù)])?

B員工總銷售是66,工作日11天,平均每天是66/11=6
A員工總銷售是6,工作日3天,但是它仍然是6/11=0.55
這明顯是錯(cuò)的
我們要解決這個(gè)問(wèn)題:讓每個(gè)員工哪天有銷售,就顯示1,否則顯示BLANK()
【度量值】優(yōu)化工作日 = sumx('日期表',if([總銷售]>0,[工作日天數(shù)]))

【度量值】優(yōu)化這期間的平均值 = DIVIDE([總銷售],[優(yōu)化工作日])?

友情提示:因?yàn)槲业陌咐校掌诒砭椭挥腥掌诤凸ぷ魅者@兩列。在你實(shí)際分析中,你的日期表中會(huì)有年,月,日,星期,等等
本案例中,我的明細(xì)是“每一天” 因?yàn)槊恳惶熘邪四暝氯?,所以在我的案例中SumX第1參數(shù)寫(xiě)'日期表'或Values('日期表'[日期])效果相同。換句話說(shuō):這張表的每一行,和日期列構(gòu)成的這張表中的每一行是等效的。
【度量值】?jī)?yōu)化工作日 = sumx('日期表',if([總銷售]>0,[工作日天數(shù)]))
【度量值】?jī)?yōu)化工作日 = sumx(Values('日期表'[日期]),if([總銷售]>0,[工作日天數(shù)]))
原理步驟:
1.sumx是迭代函數(shù),它在你指定的表中,迭代每一行。
2.【總銷售】是度量值,放到你指定的表中是有篩選功能的。
3.sumx通過(guò)第二參數(shù)判斷,總銷售大于0就返回工作日天數(shù),否則返回BLANK()。然而【工作日天數(shù)】也是度量值,也具有篩選功能,所以顯示的是每日對(duì)應(yīng)的工作日天數(shù)。(所以是1)
4.sumx寫(xiě)在度量值中,度量值將行上下文轉(zhuǎn)換成篩選上下文。

二、案例進(jìn)階
剛才,我們只是說(shuō)了一個(gè)最簡(jiǎn)單的情況,那復(fù)雜一些,例如有如下兩張表:

A員工是2020年12月1日參加工作,數(shù)據(jù)是2020/12/1~2021/12/31? ?(1年零1個(gè)月)
B員工是2020年1月1日參加工作,數(shù)據(jù)是2020/1/1~2021/12/31(2年)
這家公司只有2020年12月按休息日休息了,其它時(shí)間全上班。
我們先通過(guò)《孫興華講PowerBI火力全開(kāi)》筆記第27課03中的動(dòng)態(tài)日期表,新建日期表
你看到一些書(shū)籍上舉例,人家沒(méi)有使用動(dòng)態(tài)日期表,所以會(huì)出現(xiàn)很多空白日期
但是,實(shí)際工作中我們都使用動(dòng)態(tài)日期表,從你銷售表中日期列的最小日期到最大日期生成一個(gè)連續(xù)且不重復(fù)的日期表。
【新建表】
日期表 = 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ò)新建列確定休息日和工作日:
【新建列】工作日 = if(ISBLANK(LOOKUPVALUE('休息日'[休息日],'休息日'[休息日],'日期表'[Date])),1,0)

【度量值】總銷售 = sum('銷售表'[銷售])?
【度量值】工作日天數(shù) = sum('日期表'[工作日])
【度量值】優(yōu)化工作日 = sumx(VALUES('日期表'[月]),if([總銷售]>0,[工作日天數(shù)]))
【度量值】這期間的平均值 = DIVIDE([總銷售],[優(yōu)化工作日])?
如果,我們SumX函數(shù)第一參數(shù)只使用了【月份】列生成的表

為什么A員工2020年23天,2021年365天,應(yīng)該累計(jì)365+23=388天,可是顯示和B員工一樣都是723天?
因?yàn)閟umx第1參數(shù)用錯(cuò)表了!我們上一個(gè)案例年月日都有,所以選擇日期表的每一行和日期表的日期列是一樣的。
這個(gè)案例,有年和月,你是不是應(yīng)該選年和月?

原理:
因?yàn)槟阒皼](méi)有指定是哪一年,所以A員工只看月份,他12個(gè)月都有數(shù)據(jù),因?yàn)?021年全年12個(gè)月他都有銷售,所以總計(jì)顯示他與B員工是一樣的
當(dāng)你指定了【年月】,這時(shí),A員工2020年只有1個(gè)月有銷售,2021年是全年有銷售,他就會(huì)計(jì)算這13個(gè)月的工作日天數(shù)。
當(dāng)你的公式只能對(duì)明細(xì)生效,不能對(duì)總計(jì)生效時(shí),我們想辦法讓它對(duì)總計(jì)生效,就是改變計(jì)算顆粒度。

《孫興華講PowerBI火力全開(kāi)》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辦公自動(dòng)化、Python爬蟲(chóng)、Python數(shù)據(jù)分析、ExcelVBA、WordVBA、AccessVBA、MySQL等等
https://www.bilibili.com/read/cv10222110?