《DAX權(quán)威指南》簡體版 (第三章)02

《DAX權(quán)威指南》簡體版 (第三章)02

了解ALL,ALLEXCEPT和ALLNOBLANKROW

ALL系列函數(shù)包括ALL、ALLEXCEPT以及?ALLNOBLANKROW。

? ? ? ? ?所有這些都是一個有用的系列函數(shù):
它返回一個表的所有行或者一個列的所有值,這取決于使用的參數(shù)。

例如,下面的DAX查詢返回產(chǎn)品表中的所有行:

EVALUATE
ALL?( Product )

不能在ALL( )參數(shù)中指定一個表表達(dá)式,而必須指定一個表名的列表或列名的列表。如果使用單個列,結(jié)果是一個包含唯一值的列表,如圖3-8所示。

EVALUATE
ALL?( Product[Class] )?--ALL

參數(shù)為一個表的列表

圖3-8?對列的所有值的查詢返回所有唯一值的列表。


譯者:Class列表中可能存在一個或多個列值為Econmy、Regular、Deluxe的行,ALL(Class)的結(jié)果是該列的所有唯一值的列表,即只有Econmy、Regular、Deluxe三個值的列表。

可以在ALL函數(shù)的參數(shù)中指定來自同一個表的更多個列。如果使用多個列作為參數(shù),結(jié)果將是一個具有相同行數(shù)量的列表,其中包含這些列中現(xiàn)有值的組合列表。例如,下面的表達(dá)式生成圖3-9所示的結(jié)果。

EVALUATE
ALL?( Product[Class],Product[Color] )?
?ORDER BY Product[Color]

圖3-9 ALL對更多列的查詢返回一個僅存在有這些列值的值組合的列表。

? ? ? ?譯者補充:如上圖,[Class]列與[Color]列雖然有重復(fù)的非唯一值,例如[Class]列的行值Economy,[Color]列的行值Silver Grey、White。從單列的結(jié)果來看,似乎是不對的。

? ? ? 但是,ALL?( Product[Class],Product[Color] )是針對[Class]和[Color]兩列取唯一值,其中包含這兩列中現(xiàn)有值的組合列表中的唯一值。為方便觀察,我們換個角度看看:

? ? ? ?如圖,[Class]和[Color]列的對應(yīng)行值的兩兩組合的值,例如:Economy+Silver是一個唯一值,依次類推,Economy+Silver Grey也是唯一值……。由于在實際的運用中,ALL()的列表結(jié)果很重要,所以加了這點補充。

? ? ? ?有的人將ALL(多個列)的結(jié)果理解為:先對多個列做笛卡爾積,然后篩選其中原表中已經(jīng)存在的列值組合。這種說法對不對?并沒有答案,關(guān)鍵是DAX內(nèi)部引擎的工作原理是不能用猜想或一兩個正確的公式就可以證明的。

在ALL的變體函數(shù)中,都忽略了任何現(xiàn)有的篩選器來產(chǎn)生結(jié)果。

我們可以將這些ALL系列函數(shù)作為迭代函數(shù)的參數(shù)(如SUMX和FILTER),或者作為一個CALCULATE函數(shù)中的篩選器參數(shù)(稍后將會看到)。

如果想利用ALL函數(shù)調(diào)用某個表的大部分列,則可以使用ALLEXCEPT代替。要想從結(jié)果中排除哪些列,則需要一個表,后面再是該表中無須排除的列。

因此,?ALLEXCEPT返回一個表,即該函數(shù)指定列表之外的其他列,其中包括這些其他列表的唯一值組合的列表。

實際上,ALLEXCEPT是一種編寫DAX表達(dá)式的方法,它將自動包含在ALL非參數(shù)列的所有結(jié)果,以及之后數(shù)據(jù)模型中可能新增的新的任何額外的列。

例如,如果有一個帶有五個列的產(chǎn)品表(ProductKey,?Product Name,?Brand,?Class,?Color--產(chǎn)品代碼、產(chǎn)品名稱、品牌、類別、顏色),下面的語法產(chǎn)生相同的結(jié)果:

ALL?( Product[Product Name],Product[Brand],Product[Class] )?//?除去的三列(ALL包含的三個列)

ALLEXCEPT?( Product,?Product[ProductKey],?Product[Color] )?//?保留的兩列(相當(dāng)于ALL包含的除去這兩列之外的任何其他列)

然而,如果以后再再該表中添加兩列?:[Unit Cost]和?[Unit Price]--產(chǎn)品單位成本和產(chǎn)品(單價),那么,ALL()的結(jié)果將忽略它們,與前面ALLEXCEPT的返回結(jié)果等效。

下面的查詢返回一個表,該表除了[Code]和[Color]--產(chǎn)品代碼和產(chǎn)品顏色列之外的所有列。

ALL?(Product[Product Name],Product[Brand],Product[Class],

Product[Unit Cost],Product[Unit Price])?–-不包含[Code]和[Color]兩列,其結(jié)果等效于下面的公式:

EVALUATE
ALLEXCEPT?( Product,
Product[ProductKey],Product[Color] )

后者的好處是,不受表中新增列表的影響。

圖3-10是上述公式的結(jié)果。該結(jié)果與原表的行數(shù)相同,因為結(jié)果包含了ProductKey列,該列的每一行都是一個唯一值。結(jié)果為ALLEXCEPT參數(shù)指定列之外的其他列的組合,但可能會返回更少的行,因為返回的列值中刪除了重復(fù)值。

圖3-10,返回所有在ALLEXCEPT參數(shù)中沒有指定的列的值的組合。

前面的例子,是一個ALL函數(shù)的EVALUATE輸出語句,它執(zhí)行一個DAX表達(dá)式,而沒有任何現(xiàn)有的篩選條件。也就是說:

ALL的計算語句,它在沒有任何現(xiàn)有篩選器的情況下執(zhí)行DAX表達(dá)式。

出于這個原因,我們最好是看一個在透視表中使用ALL函數(shù)計算表的行數(shù)的例子,其中使用不同的篩選器對每個度量的單元格值進(jìn)行計算。

考慮以下度量:

[Products]?:????=?COUNTROWS?( Product )
[All Products] :=?COUNTROWS?(?ALL?( Product )?)
[All Brands] :?=?COUNTROWS?(?ALL?(?Product[Brand]?)?)

可以在圖3-11中看到每個度量的不同結(jié)果的示例。

圖3-11 [ALL Prodcte]和[ALL Brands]度量都忽略了Row lablels行的(行篩選)影響,總是顯示相同的數(shù)字。

對于每個產(chǎn)品類別(第一列中的每行),在[All Products]和[All Blands]列中都產(chǎn)生相同的數(shù)字,是因為度量公式中ALL()語句的計算忽略了透視表的每個單元格定義的篩選器。

譯者:(1)[All Products]?:=?COUNTROWS?(?ALL?( Product )?)度量,僅計算All?(Product)的結(jié)果:即Product表的全部唯一值行的計數(shù)(結(jié)果為2517)。

? ? ? ?(2)[All Brands]?:=?COUNTROWS?(?ALL?( Product[Brand] )?)度量,僅計算ALL?( Product[Brand] )的結(jié)果:即Product表的[Brand]列的唯一值行的計數(shù)(結(jié)果為12,[Brand]列表中唯一值為12個)。

當(dāng)調(diào)用關(guān)系的父表時,如果子表包含一個或多個與父表中的值不匹配的行,則會檢索額外的空行??梢允褂肁LLNOBLANKROW而不是ALL的方法來忽略結(jié)果中的這個特殊行。考慮以下度量:

[All Products]?:=?COUNTROWS?(?ALL?( Product ) )
[All NoBlank Products]?:=?COUNTROWS?(?ALLNOBLANKROW?( Product) )

[All Brands]?:=?COUNTROWS?(?ALL?( Product[Brand] ) )
[All NoBlank Brands]?:=?COUNTROWS?(?ALLNOBLANKROW?(Product[Brand] ) )

[All Sizes]?:=?COUNTROWS?(?ALL?( Product[Size] ) )

[All NoBlank Sizes]?:=?COUNTROWS?(?ALLNOBLANKROW?(Product[Size] ) )

在圖3-12中,可以看到ALL和ALLNOBLANKROW度量之間的區(qū)別。這些度量的值中,?ALL版本度量結(jié)果與對應(yīng)的ALLNOBLANKROW版本度量結(jié)果都多一個。原因是Sales表中有一些行在Product表中并沒有匹配的行,因此,實際上添加了一個額外的行,你可以在圖3-12中看到(空白)行中的結(jié)果。

你應(yīng)該注意到,?[All Sizes ]和?[All NoBlank Sizes]度量總是返回相同的值(622),該度量查詢Products[Size]列的數(shù)量。因為Products[Size]列已經(jīng)包含了一個空白值的產(chǎn)品,所以這種情況下ALL?和?ALLNOBLANKROW函數(shù)返回相同的值。

在圖3-13的示例中,有569個(blank)--空白計數(shù)的產(chǎn)品,加上額外的,其中包含對銷售表中不匹配的產(chǎn)品的引用的一個空白產(chǎn)品,總共570個。所有這些行被分組在Products[Size]列的?(空白)值中用于計算。

圖3-13透視表行包含每個Products[Size]值。第一個(空白)的值包括[Size]列的空白和銷售表中未匹配產(chǎn)品的額外空白產(chǎn)品。

當(dāng)你需要編寫一個遍歷表,然后忽略關(guān)系中不匹配的值時,應(yīng)該使用ALLNOBLANKROW。然而,通用都是使用ALL,而ALLNOBLANKROW卻很少被使用。

了解VALUES?和?DISTINCT

在前一節(jié)中,已經(jīng)看到,?ALL(一個列表)結(jié)果返回該列所有唯一值行值的表。DAX函數(shù)提供了另外兩個類似的函數(shù):VALUES?和?DISTINCT,也返回一個列表的唯一值的列。

在沒有任何其他篩選操作的情況下,如果在EVALUATE語句中使用VALUES?和?DISTINCT看起來是相同的。

但是,當(dāng)將這兩個函數(shù)分別放置在DAX度量中時,就可以觀察到它們不同的行為。因為在一個數(shù)據(jù)透視表的每個單元格中,計算發(fā)生在當(dāng)前不同的篩選子集中。

考慮下面的度量,計算Product[Brand]和Product[Size]?列唯一值的數(shù)量。

[Products]?:?=?COUNTROWS?( Product )

[Values Brands]?

:?=?COUNTROWS?(?VALUES?( Product[Brand] ) )?

[Distinct Brands]?

:=?COUNTROWS?(?DISTINCT?( Product[Brand] ) )?

[Values Sizes]?

:?=?COUNTROWS?(?VALUES?( Product[Size] ) )?

[Distinct Sizes]?

:?=?COUNTROWS?(?DISTINCT?( Product[Size] ) )

VALUES()返回當(dāng)前單元格中可見的唯一值列表,包括未匹配值的可選空白行。DISTINCT執(zhí)行相同的操作,但不返回未匹配值的空白(這是兩者的區(qū)別)。

然而, 如果空白值本身為某個列的有效值,那么,這兩個函數(shù)都包含空白行。唯一的區(qū)別是,是否需要添加空白行來處理關(guān)系中的缺失值。一個例子可能有助于說明這一差異。

如圖3- 14所示,每個產(chǎn)品類別都篩選到不同數(shù)量的產(chǎn)品。例如,Deluxe?有360個產(chǎn)品、11個獨特的brands--品牌、204個獨特的sizes--尺寸。這時,VALUES?和?DISTINCT返回這些相同的結(jié)果。只有一個例外:在數(shù)據(jù)透視表之中的產(chǎn)品類別行的(blank)—(空白),其結(jié)果實際上包括增加的一行,以顯示不匹配產(chǎn)品的銷售金額的值。

圖3-14的值和區(qū)別只在將空白的產(chǎn)品添加到模型中,以包含那些未匹配的行,這在報告的(空白)行中是可見的。

在圖3-14中,另一個差異是可見的。VALUES()?應(yīng)用于Product[Brand]列返回的值比DISTINCT()應(yīng)用于同一列的值要多。

但是,這不會發(fā)生在DISTINCT()應(yīng)用到Product[Brand]列的值上,它返回的值與對應(yīng)列上的值相同。因為DISTINCT()的Products[Size]列包含至少一個產(chǎn)品的空白值,因此添加的空白產(chǎn)品不會為[Distinct Sizes]列添加一個新的唯一值。

當(dāng)沒有篩選器時,DISTINCT()的行為對應(yīng)于ALLNOBLANKROW(),而VALUES()的行為對應(yīng)于ALL()。

比較特殊的是,VALUES()也接受一個表作為參數(shù)。在這種情況下,它將返回當(dāng)前單元格中可見的整個表,并有選擇地包括未匹配關(guān)系的空行。

例如,在數(shù)據(jù)模型中考慮以下度量,其中Sales表與Product產(chǎn)品表具有關(guān)系,并包含與產(chǎn)品鍵不匹配的任何現(xiàn)有產(chǎn)品的事務(wù)記錄。

[Products]?:=?COUNTROWS?( Product )
[Values Products]?:=?COUNTROWS?(?VALUES?( Product ) )
[All NoBlank Products]?:=?COUNTROWS?(?ALLNOBLANKROW( Product))
[All Products]?:=?COUNTROWS?(?ALL?( Product ) )?

可以在圖3-15中看到,在這種情況下,當(dāng)沒有篩選器時,VALUES的結(jié)果對應(yīng)于ALL的行為,包括添加的空白行,以顯示未匹配產(chǎn)品的銷售額。在這種情況下,不能在一個表上使用DISTINCT。

如果需要刪除一列中重復(fù)的行,?DAX函數(shù)中沒有單獨這樣的函數(shù)來刪除重復(fù)的行(這時必須使用SUMMARIZE(),稍后將在第9章看到)。

然而, 當(dāng)沒有篩選器時,[Products]度量計算表中的行數(shù),并忽略一個可能的空白行,該行為與ALLNOBLANKROW()相同。

圖3-15的值,并考慮在產(chǎn)品表中添加空白行以獲得不匹配的銷售值。

譯者:在學(xué)習(xí)完列表關(guān)系后,ALL()行為與VALUES()行為是有區(qū)別的:ALL()行為在于創(chuàng)建一個去掉關(guān)系的唯一值列表(不能用于篩選等),VALUES()的唯一值結(jié)果列表間保持原列表關(guān)系。

使用VALUES創(chuàng)建標(biāo)量值

即使VALUES是一個表函數(shù),也會經(jīng)常使用它來計算標(biāo)量值。在這一節(jié)中將學(xué)習(xí)到DAX的一個特殊特性。例如,可以在表達(dá)式中設(shè)置VALUES(),如下面的一個DAX--[ColorName]度量,用于顯示顏色名稱,以確保選擇的為相同顏色的所有產(chǎn)品

[Color Name]?:=?IF?(COUNTROWS?(
? ? ? ? ? ? ? ? ? ? VALUES?( Product[Color] ) ) =?1,VALUES?( Product[Color] ))??

譯者:這是使用IF()測試一列中布爾值(真/假條件)的第一種方法。實際業(yè)務(wù)場景中經(jīng)常用到,后面將有更優(yōu)化的方法介紹。

可以在圖3-16中看到結(jié)果。當(dāng)[ColorName]度量結(jié)果包含空白時,意味著有兩個或更多不同的顏色。

圖3-16當(dāng)VALUES()返回一行,可以使用它將結(jié)果轉(zhuǎn)換為一個標(biāo)量值,比如[Color Name]度量。

有趣的一點是,我們使用VALUES()作為標(biāo)量值的結(jié)果,即使它返回一個表。這不是VALUES的特殊行為,但它代表DAX語言更一般的行為:

如果需要一個表表達(dá)式返回一行或一列,并需要它自動完成,則可以使用任何表表達(dá)式來將列表轉(zhuǎn)換為標(biāo)量值(即將列表轉(zhuǎn)換為值列表)。

實踐中,如果結(jié)果正好為一行或一列,可以使用任何表表達(dá)式作為一個標(biāo)量值。而當(dāng)表返回多行時,在執(zhí)行時會出現(xiàn)這樣一個錯誤:“一個多值的表是由其他方式提供的。”

因此,你應(yīng)該保持該標(biāo)量值的轉(zhuǎn)換條件,使表表達(dá)式返回一個不同的多行結(jié)果?(你應(yīng)該已經(jīng)知道,當(dāng)你寫DAX公式時,該表表達(dá)式只返回一行)。前面的[Color Name]度量示例,使用COUNTROWS?(?VALUES?( Product[Color] ) ) =?1:即COUNTROWS()檢查Color--顏色列在Products--產(chǎn)品表里的選擇是一個值。

一個更簡單的完全相同的控制方法是使用HASONEVALUE,它執(zhí)行同樣的檢查,如果列只有一個值,返回TRUE,否則返回FALSE。以下兩個語法是等價的:

COUNTROWS?(?VALUES?( ) ) =?1,HASONEVALUE?( )

你應(yīng)該用HASONEVALUE代替COUNTROWS,這有兩個原因:可讀性更強,以及可以稍快一些。下面是一個更好的基于HASONEVALUE設(shè)置的度量:

[Color Name]。

[Color Name]?:= IF (HASONEVALUE ( Product[Color] ),?VALUES ( Product[Color] ))??

?經(jīng)常使用值作為標(biāo)量表達(dá)式的原因是:在不同的篩選條件下,它返回單個列,或者返回單個行。在許多DAX模式中,使用VALUES()作為標(biāo)量表達(dá)式是很常見的,并且在本書中反復(fù)出現(xiàn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容