【DAX圣經(jīng)】第三章:使用基本表函數(shù)(2)

理解 ALL, ALLEXCEPT, and ALLNOBLANKROW

ALL 都是一個(gè)有用的函數(shù),它返回一個(gè)表的所有行或一個(gè)列的所有值,這取決于您所使用的參數(shù)。例如,下面的DAX查詢返回產(chǎn)品表中的所有行

EVALUATE
ALL ( Product )

你不能在 ALL 參數(shù)中指定一個(gè)表表達(dá)式。您必須指定表名或列名列表。如果您使用單個(gè)列,那么結(jié)果就是一張?jiān)砣ブ睾笮纬傻奈ㄒ恢盗斜恚鐖D3-8所示。

EVALUATE 
ALL ( Product[Class] )
圖3-8 對(duì)列的所有值的查詢返回一個(gè)所有惟一值的列表

你可以在 ALL函數(shù)的參數(shù)中指定來(lái)自同一個(gè)表的更多列。如果您使用許多列,那么結(jié)果將是一張包含了這些列中已有的值組合的列表(可以理解為對(duì)多個(gè)列做笛卡爾積,然后篩選其中原表中已經(jīng)存在的列組合)。例如,下面的表達(dá)式產(chǎn)生如圖3-9所示的結(jié)果:

EVALUATE 
ALL ( Product[Class], Product[Color] ) 
ORDER BY Product[Color]
圖3-9 關(guān)于更多列的all函數(shù)查詢返回一個(gè)現(xiàn)有的值組合的列表

在所有的變體中,ALL函數(shù)忽略了任何現(xiàn)有的過(guò)濾器來(lái)產(chǎn)生它的結(jié)果。您可以將ALL函數(shù)用作迭代函數(shù)的參數(shù),例如SUMX和FILTER,或者作為CALCULATE函數(shù)中的篩選參數(shù)(稍后您將看到)

如果您想要在一個(gè)ALL函數(shù)調(diào)用中包含表格的大部分列,您可以使用ALLEXCEPT函數(shù)來(lái)代替。ALLEXCEPT函數(shù)的語(yǔ)法需要一個(gè)表,后面是您想要從結(jié)果中排除的列。因此,在表格的其他列中,ALLEXCEPT返回一張表,其中包含了其他列現(xiàn)有的值組合的唯一列表。

在實(shí)際運(yùn)用中,這是一種編寫DAX表達(dá)式的方法,它將自動(dòng)包含非參數(shù)列的所有結(jié)果,以及在之后的表模型中可能出現(xiàn)的任何額外的列。例如,如果您有一個(gè)包含5個(gè)列(ProductKey, Product Name, Brand, Class, Color)的產(chǎn)品表,那么下面的語(yǔ)法就會(huì)產(chǎn)生相同的結(jié)果

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

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

但是,如果您稍后添加兩列 Product[Unit Cost]和Product[Unit Price],那么ALL函數(shù)的結(jié)果會(huì)忽略它們,而ALLEXCEPT函數(shù)則將返回等效的:

ALL ( 

Product[Product Name], 

Product[Brand], 

Product[Class],

Product[Unit Cost], 

Product[Unit Price]

 )

下列查詢返回一個(gè)表,該表除了產(chǎn)品表之外的Product Code和Color以外的所有列。圖3-10的結(jié)果與原始表的行數(shù)相同,因?yàn)榻Y(jié)果包括ProductKey列,它每一行具有惟一的值。結(jié)果中的其他列組合可能會(huì)返回較少的行數(shù),因?yàn)锳LLEXCEPT消除了返回列中值的重復(fù)組合。

EVALUATE 

ALLEXCEPT ( Product, Product[ProductKey], Product[Color] )
圖3-10 ALLEXCEPT返回現(xiàn)有的所有非參數(shù)指定列的值的組合

在前面的例子中,您已經(jīng)在一個(gè)EVALUATE語(yǔ)句中看到了ALL函數(shù),它執(zhí)行DAX表達(dá)式,而沒(méi)有任何現(xiàn)有的篩選條件。出于這個(gè)原因,最好是看一個(gè)在透視表中使用ALL函數(shù)計(jì)算表的行數(shù)的例子,這些例子中每個(gè)單元格使用不同的篩選條件來(lái)計(jì)算度量值。考慮以下度量值:

[Products] := COUNTROWS ( Product ) 

[All Products] := COUNTROWS ( ALL ( Product ) ) 

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

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

圖3-11所有產(chǎn)品和所有品牌都忽略了行上的類別并且總是顯示相同的數(shù)字

對(duì)于每一個(gè)產(chǎn)品類別,在All Products和All Colors列中,總是有相同的結(jié)果。在ALL函數(shù)的計(jì)算中忽略了透視表中單元格的篩選條件。

當(dāng)你調(diào)用ALL函數(shù)在一個(gè)關(guān)系的父表時(shí),如果子表包含一個(gè)或多個(gè)行在父表中不匹配任何值的行,就會(huì)返回一個(gè)額外的空白行。您可以通過(guò)使用 ALLNOBLANKROW 函數(shù) 代替ALL函數(shù)來(lái)忽略這個(gè)特殊的行。

考慮下面的度量值:

[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ū)別。對(duì)于Product表 和 the Products[Model]列,ALL版本的度量值比ALLNOBLANKROW版本多返回一行。原因是銷售表中有一些行,在產(chǎn)品表中沒(méi)有與之匹配的行,因此額外的一行實(shí)際上被添加到產(chǎn)品表中,您可以在圖3-12中看到(空白)行中的結(jié)果。

圖3-12 如果目標(biāo)表包含一個(gè)因?yàn)椴黄ヅ涠a(chǎn)生額外的空白行,那么ALL和 ALLNoBlank度量值都是不同的

您應(yīng)該注意到, All Sizes和All NoBlank Sizes計(jì)算結(jié)果總是相同。這些度量查詢Products[Size]列的數(shù)量。在這種情況下,ALL和ALLNOBLANKROW函數(shù)返回相同的值,因?yàn)?Products[Size]列已經(jīng)包含了一個(gè)產(chǎn)品的空白值。在圖3-13的例子中,有569個(gè)空白大小的產(chǎn)品,加上一個(gè)額外的無(wú)法引用銷售表產(chǎn)品空白產(chǎn)品,總共有570個(gè)。對(duì)于Products[Size]列,所有這些行都被分組在同一個(gè)的(空白)值中。

圖3-13 透視表的行是每個(gè)產(chǎn)品名稱的SIZE。第一個(gè)(空白)值的大小包括空白SIZE的產(chǎn)品和沒(méi)有在銷售表中匹配到的額外空白產(chǎn)品

只有當(dāng)你寫了一個(gè)DAX公式需要它忽略了關(guān)系中不匹配的值時(shí),你才應(yīng)該使用ALLNOBLANKROW。然而,相較于ALL函數(shù),ALL的使用則顯得更為通用,而ALLNOBLANKROW用的則很少。

理解 VALUES和 DISTINCT

在上一節(jié)中,您已經(jīng)看到,ALL主要用于返回一個(gè)列中所有惟一值的表。DAX提供了另外兩個(gè)類似的函數(shù),它們返回一個(gè)列的惟一值列表:VALUES和DISTINCT

如果在沒(méi)有任何其他篩選條件情況下,在EVALUATE語(yǔ)句中 VALUES和 DISTINCT似乎是相同的。然而,當(dāng)你把這些函數(shù)放在DAX度量值中時(shí),你可以觀察到一個(gè)不同的行為,因?yàn)橛?jì)算發(fā)生在一個(gè)透視表的每個(gè)單元格的不同上下文中??紤]以下在產(chǎn)品表中Brand列和 Size 列計(jì)算不同唯一值數(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)前可見(jiàn)單元中惟一值列表,包括沒(méi)有匹配的空白行。 DISTINCT同樣,但是不返回沒(méi)有匹配的空白行。但是,如果一個(gè)空白值作為列的有效值出現(xiàn),那么這兩個(gè)函數(shù)都將包含一個(gè)空行。唯一的區(qū)別是添加了空白行來(lái)處理關(guān)系中缺失值

一個(gè)例子可能會(huì)幫助你區(qū)分這種不同。正如表3-14,每個(gè)產(chǎn)品等級(jí)篩選出不同數(shù)量的產(chǎn)品。比如Deluxe有360種產(chǎn)品,有11個(gè)不同的品牌和204個(gè)不同的尺碼。 VALUES 和 DISTINCT 返回相同的結(jié)果,只有一個(gè)例外:透視表中行的(空白)產(chǎn)品類。結(jié)果增加了一個(gè)虛擬行,以顯示在Sales Amount中沒(méi)有匹配到的產(chǎn)品。

圖3-14 VALUES 和 DISTINCT 的區(qū)別,只有當(dāng)一個(gè)空白產(chǎn)品被添加到報(bào)告的(空白)行中是可見(jiàn)的模型中以包含不匹配的行

另一個(gè)在圖3-14中可見(jiàn)的區(qū)別在 Grand Total中。 VALUES 應(yīng)用于 Product[Brand],返回的值比應(yīng)用在同樣列上DISTINCT的值多一個(gè)。然而,這并不會(huì)發(fā)生在 VALUES 應(yīng)用于Products[Size]的值上,后者返回的值與 DISTINCT應(yīng)用在同樣的列上相同。這個(gè)原因是 Distinct Sizes 列包含至少一個(gè)產(chǎn)品的空白值,因此添加的空白產(chǎn)品不會(huì)為 Distinct Sizes 列添加一個(gè)新的惟一值。

當(dāng)沒(méi)有篩選條件時(shí), DISTINCT行為與ALLNOBLANKROW的行為相同,與此對(duì)比,VALUES行為與ALL行為相同。

VALUES也接受一張表作為參數(shù)。在這種情況下,它返回在當(dāng)前可見(jiàn)的整個(gè)表,同時(shí)也包括沒(méi)有匹配的空白行。例如,在數(shù)據(jù)模型中考慮以下度量值,其中Sales表與 Product 表有關(guān)系,并包含與產(chǎn)品主鍵不匹配的交易。

[Products] := COUNTROWS ( Product )

[Values Products] := COUNTROWS ( VALUES ( Product ) )

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

[All Products] := COUNTROWS ( ALL ( Product ) )

VALUES作為標(biāo)量值使用

即使 VALUES 是一個(gè)表函數(shù),您也經(jīng)常使用它來(lái)計(jì)算標(biāo)量值,因?yàn)樵贒AX中有一個(gè)特殊的特性,您將在本節(jié)中學(xué)習(xí)。例如,您可以在表達(dá)式中找到VALUES,比如下面的表達(dá)式,它會(huì)顯示顏色名稱,以確保某一特定選擇的產(chǎn)品都具有相同的顏色:

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

您可以在圖3-15中看到結(jié)果。當(dāng)Color Name列包含空白時(shí),這意味著有兩種或更多不同的顏色

圖3-15當(dāng)VALUES返回一行時(shí),您可以將其用作標(biāo)量值,例如Color Name 度量值

這里的有趣之處在于,我們將VALUES的結(jié)果作為標(biāo)量值,即使它返回一個(gè)表。這不是一種VALUES特殊的行為而是DAX語(yǔ)言一種更普遍的行為。

如果一個(gè)表表達(dá)式返回一個(gè)帶有一行和一列的表,那么如果需要的話,可以自動(dòng)轉(zhuǎn)換成為標(biāo)量值。

在實(shí)踐中,如果結(jié)果恰好有一行和一列,您可能會(huì)使用任何表表達(dá)式作為標(biāo)量值。當(dāng)表格返回更多的行時(shí),您會(huì)在執(zhí)行時(shí)得到這個(gè)錯(cuò)誤:“在期望單個(gè)值的地方提供了多個(gè)值的表。“出于這個(gè)原因,您應(yīng)該始終編寫一個(gè)返回不同結(jié)果的條件來(lái)確保能夠轉(zhuǎn)換為標(biāo)量值,以防表表達(dá)式返回更多的行(您應(yīng)該已經(jīng)知道,當(dāng)您編寫DAX表達(dá)式時(shí),表表達(dá)式是否只返回一行)。

前面例子的 Color Name度量使用COUNTROWS來(lái)檢查產(chǎn)品表的 Color 列是否只有一個(gè)值。一種更簡(jiǎn)單的方法是使用HASONEVALUE,它執(zhí)行相同的檢查,如果列只有一個(gè)值返回的值,反之則返回 FALSE 。以下兩個(gè)語(yǔ)法是等價(jià)的

COUNTROWS ( VALUES ( <column> ) ) = 1

HASONEVALUE ( <column> )

您應(yīng)該使用HASONEVALUE而不是COUNTROWS,原因有兩個(gè):它更易于閱讀,而且可能會(huì)稍微快一些。下面是基于HASONEVALUE的 Color Name 度量值的更好的實(shí)現(xiàn):

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

您經(jīng)常使用 VALUES 作為標(biāo)量表達(dá)式的原因是它返回單個(gè)列,并且可能返回單行,這取決于執(zhí)行上下文。在許多DAX模式中, VALUES 作為標(biāo)量表達(dá)式是很常見(jiàn)的,并且在本書中反復(fù)出現(xiàn)。

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

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

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