【DAX學習】2触菜、理解計算列和度量值

image.png

1、DAX基礎(chǔ)語法

DAX公式一般的格式是將表名用單引號括起來哀峻,后跟用方括號括起的列名涡相,如下:

'Sales'[Quantity]

但是標準是在列引用中始終使用表名,在度量引用中始終避免使用表名剩蟀。
在以后介紹了上下文轉(zhuǎn)換之后催蝗,我們會了解到這個標準背后的基本原理

Sales[Quantity] * 2  -- 這是計算列的寫法
[Sales Amount] * 2   -- 這是度量值的寫法
'--'和'//'在DAX中表示單行注釋
多行注釋以'/*'開始,以'*/'結(jié)束育特。

1.1 DAX數(shù)據(jù)類型
DAX支持七種數(shù)據(jù)類型參與計算

image.png

DAX會在操作符需要時自動將字符串轉(zhuǎn)換為數(shù)字丙号,并將數(shù)字轉(zhuǎn)換為字符串。
例如缰冤,如果我們使用連接字符串的&操作符犬缨,DAX將其參數(shù)轉(zhuǎn)換為字符串。
下面的公式以字符串形式返回“54”:

= 5 & 4

另一方面棉浸,該公式返回一個值為9的整數(shù)結(jié)果:

= "5" + "4"

但是上述方式并不推薦怀薛,如果真想轉(zhuǎn)換數(shù)據(jù)類型,推薦顯式轉(zhuǎn)換迷郑,上面的例子可以改為:

= VALUE ( "5" ) + VALUE ( "4" )

1.2 DAX操作符

image.png

1.3 構(gòu)造表
在DAX中枝恋,我們可以直接在代碼中定義匿名表
如果表只有一列嗡害,那么語法上只需要一個值列表—每一行一個值—由花括號分隔焚碌。
我們可以用括號分隔多行,如果表只有一列就漾,括號是可選的呐能。
例如,以下兩個定義是等價的:

{ "Red", "Blue", "White" }
{ ( "Red" ), ( "Blue" ), ( "White" ) }

如果表有多列,括號是必需的摆出。
每一列的所有行都應該有相同的數(shù)據(jù)類型;否則朗徊,DAX將自動將列轉(zhuǎn)換為一種數(shù)據(jù)類型,這種數(shù)據(jù)類型可以容納同一列的不同行中提供的所有數(shù)據(jù)類型偎漫。

{
( "A", 10, 1.5, DATE ( 2017, 1, 1 ), CURRENCY ( 199.99 ), TRUE ),
( "B", 20, 2.5, DATE ( 2017, 1, 2 ), CURRENCY ( 249.99 ), FALSE ), 
( "C", 30, 3.5, DATE ( 2017, 1, 3 ), CURRENCY ( 299.99 ), FALSE )
}

表構(gòu)造函數(shù)通常與IN操作符一起使用爷恳。例如,:

'Product'[Color] IN { "Red", "Blue", "White" }
( 'Date'[Year], 'Date'[MonthNumber] ) IN { ( 2017, 12 ), ( 2018, 1 ) }

以下示例展示了使用IN操作符比較一組列(元組)
這種方式不能與比較運算符一起使用象踊,所以以下寫法是無效的

( 'Date'[Year], 'Date'[MonthNumber] ) = ( 2007, 12 )

但是温亲,我們可以用以下方式來重寫它

( 'Date'[Year], 'Date'[MonthNumber] ) IN { ( 2007, 12 ) }

1.4 條件語句

在DAX中,我們可以使用IF函數(shù)編寫條件表達式杯矩。例如:

IF (
Sales[Quantity] > 1, "MULTI", "SINGLE"
)

IF函數(shù)有三個參數(shù)栈虚,但只有前兩個是必需的。第三個選項是可選的史隆,默認為空白魂务。所以以下兩種寫法都是一樣的

IF (
Sales[Quantity] > 1, Sales[Quantity]
)

IF (
Sales[Quantity] > 1, Sales[Quantity], BLANK ()
)

2、計算列和度量值的區(qū)別

2.1 計算列

計算列是添加到模型中的新列泌射,但它不是從數(shù)據(jù)源加載的粘姜,而是通過使用DAX公式創(chuàng)建的。
計算列和表格中的其他列一樣熔酷,還可以使用計算列來定義關(guān)系孤紧。
定義計算列的DAX表達式在計算列所屬表的當前行上下文中操作。對列的任何引用都將返回該列的當前行值拒秘,我們不能直接訪問其他行的值号显。所有計算的列都占用內(nèi)存,并且都是在表處理期間計算的翼抠。

在創(chuàng)建復雜的計算列時咙轩,存放在內(nèi)存非常有用。計算復雜計算列所需的時間始終是處理時間而不是查詢時間阴颖,這樣可以獲得更好的用戶體驗活喊。不過,要注意計算列使用了寶貴的RAM量愧。
例如钾菊,如果我們有一個復雜的計算列公式,我們可能會試圖將計算步驟拆分到不同的中間列中偎肃。盡管這種方式在項目開發(fā)期間很有用煞烫,但在生產(chǎn)中卻是一個壞習慣,因為每個中間計算都存儲在RAM中累颂,浪費了寶貴的空間滞详。
如果模型是基于DirectQuery的凛俱,那么行為就會有很大的不同。在DirectQuery模式下料饥,當表格引擎查詢數(shù)據(jù)源時蒲犬,計算的列是動態(tài)計算的。這可能導致數(shù)據(jù)源執(zhí)行大量查詢岸啡,從而產(chǎn)生速度較慢的模型原叮。

例如,我們可以利用下單時間和交貨日期兩列數(shù)據(jù)巡蘸,兩列相減得出出交付訂單所需的天數(shù)奋隶,以下是計算列的公式:

Sales[DaysToDeliver] = INT ( Sales[Delivery Date] - Sales[Order Date] )

2.2 度量值
度量值是用聚合函數(shù)計算出來的值,它的結(jié)果只有一個悦荒,而計算列得出的結(jié)果是一列的值
例如唯欣,在Sales表中定義一些計算列來計算毛利率金額:

Sales[SalesAmount] = Sales[Quantity] * Sales[Net Price] 
Sales[TotalCost] = Sales[Quantity] * Sales[Unit Cost] 
Sales[GrossMargin] = Sales[SalesAmount] – Sales[TotalCost]
image.png

如果想顯示毛利占銷售額的百分比,可以使用以下公式創(chuàng)建一個計算列:

Sales[GrossMarginPct] = Sales[GrossMargin] / Sales[SalesAmount]

這個公式在行級別上計算正確的值逾冬,如下圖所示黍聂,但是在總體總數(shù)級別上,結(jié)果顯然是錯誤的身腻。

image.png

可以看出來,551.46%是所有毛利占比的總和匹厘,這種計算方式顯然是錯誤的嘀趟,我們應該以所有毛利的總和除以所有銷售額的總和
如果需要對聚合值進行操作,而不是逐行操作愈诚,則必須創(chuàng)建度量她按。我們使用:=來定義度量值,而不是等號=炕柔,以便在代碼中更容易區(qū)分度量和計算列酌泰。
定義GrossMarginPct作為度量值后,結(jié)果是正確的匕累,如下圖所示陵刹。

GrossMarginPct := SUM ( Sales[GrossMargin] ) / SUM (Sales[SalesAmount] )
image.png

度量值和計算列都使用DAX表達式,不同之處在于計算的環(huán)境欢嘿。

計算列的值是在數(shù)據(jù)刷新期間計算的衰琐,它使用當前行作為上下文。結(jié)果不依賴于用戶在報表上的操作炼蹦。

度量值對當前上下文定義的數(shù)據(jù)聚合進行操作羡宙。例如,在透視表中掐隐,根據(jù)透視表的行過濾源表狗热,并使用這些過濾器聚合和計算數(shù)據(jù)。換句話說,度量值總是在計算環(huán)境下對數(shù)據(jù)的聚合進行操作(關(guān)于計算上下文會在之后進一步說明)匿刮。

因此僧凰,當在度量值中使用SUM(Sales[SalesAmount])時,我們指的是篩選聚合的所有行的總和僻焚。但是允悦,當我們在計算列中使用Sales[SalesAmount]時,我們指的是當前行中SalesAmount列的值虑啤。

需要在表中定義度量值隙弛,但是并不真正屬于表格。實際上狞山,我們可以將度量值從一個表移動到另一個表全闷,而不會丟失其功能。

因為度量值在查詢時計算萍启,它不會消耗內(nèi)存和磁盤空間总珠。通常,當我們可以用兩種方式表達計算時勘纯,度量值是首選局服。應該將計算列的使用限制在少數(shù)嚴格需要它們的情況下。具有Excel經(jīng)驗的用戶通常更喜歡計算列而不是度量驳遵,因為計算列非常類似于在Excel中計算的方式淫奔。然而,在DAX中計算值的最好方法是通過度量值堤结。

此系列是對The_Definitive_Guide_to_DAX第2版的學習筆記

歡迎關(guān)注微信公眾號:紙上躬行君

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末唆迁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子竞穷,更是在濱河造成了極大的恐慌唐责,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瘾带,死亡現(xiàn)場離奇詭異鼠哥,居然都是意外死亡,警方通過查閱死者的電腦和手機月弛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門肴盏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人帽衙,你說我怎么就攤上這事菜皂。” “怎么了厉萝?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵恍飘,是天一觀的道長榨崩。 經(jīng)常有香客問我,道長章母,這世上最難降的妖魔是什么母蛛? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮乳怎,結(jié)果婚禮上彩郊,老公的妹妹穿的比我還像新娘。我一直安慰自己蚪缀,他們只是感情好秫逝,可當我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著询枚,像睡著了一般违帆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上金蜀,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天刷后,我揣著相機與錄音,去河邊找鬼渊抄。 笑死尝胆,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的护桦。 我是一名探鬼主播班巩,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼嘶炭!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起逊桦,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤眨猎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后强经,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體睡陪,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年匿情,在試婚紗的時候發(fā)現(xiàn)自己被綠了兰迫。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡炬称,死狀恐怖汁果,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情玲躯,我是刑警寧澤据德,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布鳄乏,位于F島的核電站,受9級特大地震影響棘利,放射性物質(zhì)發(fā)生泄漏橱野。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一善玫、第九天 我趴在偏房一處隱蔽的房頂上張望水援。 院中可真熱鬧,春花似錦茅郎、人聲如沸蜗元。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽许帐。三九已至,卻和暖如春毕谴,著一層夾襖步出監(jiān)牢的瞬間成畦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工涝开, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留循帐,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓舀武,卻偏偏與公主長得像拄养,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子银舱,可洞房花燭夜當晚...
    茶點故事閱讀 45,086評論 2 355