篩選與擴展表
(來自官方簡體筆記)
? ? DAX里的篩選表
? ? ? 本文介紹了一些可用于在DAX中篩選表的技術(shù)厚掷, 顯示了在你了解它們后可以避免的可能的錯誤行為及缺陷彭羹, 特別是當使用雙向篩選器時尖淘。
? ? ? ? 在學(xué)習(xí) DAX 時, 最難做的事情之一就是需要擺脫常識性的推理麻诀, 學(xué)習(xí)遵循一組新的規(guī)則: 它們是在邏輯語境中定義的献酗、并且有些獨特的思維。如果你之前有一定的編程或查詢基礎(chǔ)偎窘, 你將傾向于將以前的知識映射到 DAX乌助, 而忘記遵循使用該語言的基本規(guī)則的簡單思維路徑。
? ? ? 在開始時陌知,我想舉幾個例來充當思維陷阱(坑)他托。所有這些示例都是如何篩選表的基本變體。這些計算的數(shù)字本身沒有意義仆葡。我們的目標就是用它們理解這個理論赏参。把它映射到真實的例子是留給讀者的一個有趣的練習(xí)。
? ? ? 讓我們從以下代碼開始沿盅,它返回所有行的相同值:
DEFINE
MEASURE Sales[Test]=
CALCULATE (SUM ( Sales[Quantity])把篓,
ALL( 'Product' ) )
EVALUATE
ADDCOLUMNS ( VALUES ( 'Product'[Color] ), "Test"嗡呼,[Test] )
其結(jié)果是:
按此模式再舉一例:
接著解釋前面的公式返回所有行的相同值的原因是:
? ? ? ADDCOLUMNS在Product[Color]列上創(chuàng)建了一個行篩選纸俭,但是該度量包含了ALL ( 'Product' ),它消除了由篩選轉(zhuǎn)換生成的篩選器的影響南窗。通過在Sales-銷售表(事實表)上揍很,而不是產(chǎn)品表上執(zhí)行ALL()操作,你可以獲得類似的效果万伤。事實上窒悔,如果你定義以下度量:
DEFINE
MEASURE Sales[Test] =
CALCULATE(SUM( Sales[Quantity] ),
ALL( 'Product'[ProductKey] ))
EVALUATE
ADDCOLUMNS( VALUES ( 'Product'[Color] )敌买,
"Test"简珠,[Test] )
? ? ? 結(jié)果是:同樣的值重復(fù)出現(xiàn)在所有行中。雖然這是需要的正確值, 但很多人并不真正能理解為什么會發(fā)生這種情況聋庵。事實上膘融, 在考慮如何在 DAX 中使用Product[Color]列篩選Sales-銷售表時,這是一個普遍的想法:
? ? (1)ADDCOLUMNS 通過 " Color" 列篩選Product表祭玉。
? ? (2)Product[Color]上的篩選器依據(jù)Product [ProductKey] 列的一組值提供篩選氧映。
? ? ? 上述Product[ProductKey]列的子集將成為Sales [ProductKey]上的篩選器, 并將此篩選應(yīng)用于Sales-銷售表脱货, 結(jié)果只對給定的Color-顏色進行銷售計算岛都。換句話說,Product[Color]上的篩選器將成為Sales[ProductKey] 的篩選器振峻。不幸的是臼疫,這是不正確的。如果后者是真的扣孟, 則下面的代碼將返回所有行的相同值烫堤, 而實際上每一行都返回了不同的值:
DEFINE
MEASURE Sales[Test] =
CALCULATE(SUM( Sales[Quantity] ),ALL( Sales[ProductKey] ) )
EVALUATE
ADDCOLUMNS(VALUES( 'Product'[Color] )哈打,
"Test"塔逃,[Test] )
? 結(jié)果為:
? ? ? 這里,通過使用? ALL( Sales[ProductKey] )料仗,你清除了Sales[ProductKey]列上的任何篩選器湾盗,但是color-顏色列的篩選器仍然有效。這種行為的原因非常簡單:篩選器從來沒有被放在Sales[ProductKey]列上立轧,該篩選器只針對Product [Color]列格粪。
? ? ? 如果你認為—就像你在關(guān)系數(shù)據(jù)庫中所做的那樣:篩選器通過把兩個表連接在一起來工作,那么氛改,你就錯了帐萎。進一步的測試,如果你仍然不相信我胜卤,你可以再嘗試以下的DAX
DEFINE
MEASURE Sales[Test] =
CALCULATE(
SUM ( Sales[Quantity] )疆导, ALL( 'Product'[ProductKey]) )
EVALUATE
ADDCOLUMNS ( VALUES ( 'Product'[Color] ),
"Test"葛躏,[Test] )
? ? ? 同樣澈段,結(jié)果對于每一行都有不同的值。即使你從Product[ProductKey]中移除篩選器舰攒,Product[Color]列的篩選器仍然保持不變败富。關(guān)鍵是:這種行為與篩選的工作方式?jīng)]有任何聯(lián)系。篩選器只能通過使用擴展表來定義(在本系列的其他文章里摩窃,你了解更多關(guān)于擴展表的知識)兽叮。
? ? ? 擴展版的Sales表包含Product列。因此,當篩選Product[Color]時鹦聪,它將同時篩選Sales表账阻,而無需考慮關(guān)系、字段鍵或任何其他“關(guān)系”工具泽本。因為擴展模型(Sales表)包含Product[Color]列宰僧,所以,可以通過篩選Product[Color]來篩選Sales銷售表观挎。
? ? ? ? 那么,為什么這個方法可以去掉篩選器呢?
DEFINE
MEASURE Sales[Test] =
CALCULATE(
SUM ( Sales[Quantity] )段化,ALL ( Sales ))
EVALUATE
ADDCOLUMNS ( VALUES ( 'Product'[Color] )嘁捷,
"Test",[Test] )
? ? ? 原因是显熏, 此代碼清除了Product[Color]上的篩選器雄嚣。因為ALL ( Sales ) 刪除了擴展Sales表中的任何列上的任何篩選器。請記状 :
? ? ? 在 DAX 中缓升, 當你引用一個篩選器參數(shù)中的表時,這樣的表總是被擴展蕴轨。
? ? ? ? 因此港谊,ALL( Sales ) 參數(shù)不僅從Sales的任何原列表中移除篩選器(正如我們所看到的那樣,在這種情況下不會產(chǎn)生任何效果)橙弱,但它也從Sales的關(guān)系列中移除篩選器歧寺,其中當然也包括Product[Color]。
? ? ? ? 如果你還需要說服自己棘脐,你可以使用Sales表的所有列斜筐, 這時會注意到Product[Color]上的篩選器仍然在那里。刪除它的唯一方法是:
? ? ? ? 篩選Product表或使用擴展的Sales表蛀缝。
? ? ? ? 當激活A(yù)nalysisServices 2016或PowerBI 中的雙向篩選時顷链, 該方案變得更加復(fù)雜。事實上屈梁,雙向篩選并不適用于表的擴展嗤练。相反,雙向篩選是通過在執(zhí)行查詢時以顯式方式加入事實表篩選器來執(zhí)行的俘闯。這就造成了在使用該篩選器時需要額外的注意潭苞。
? ? 雙向篩選與擴展表
? ? ? 請考慮以下模型,通過使用中間維度表(Accounts)和(AccountCustomer)橋接表將客戶鏈接到Transactions-交易記錄表真朗。為了使該多到多的關(guān)系工作此疹,我們啟用了AccountCustomer橋接表和Account表之間的雙向篩選關(guān)系。
? ? ? 一個簡單的報告,顯示生成CustomerName的金額總和蝗碎,遍歷到多到多的關(guān)系湖笨, 并生成一個類似以下的正確結(jié)果:
? ? ? ? 有必要回顧一下這里所發(fā)生的事情。
? ? ? ? Customer客戶正在篩選bridge橋表蹦骑, 而橋接表則通過雙向關(guān)系篩選到Account帳戶表慈省。作為最后一步, Account表將篩選事務(wù)記錄表--Transactions眠菇。讓我們更準確地說說擴展表的幾個方面:
? ? ? (1)AccountCustomer 擴展到Customer表边败。因此, Customer表上的篩選器也會篩選橋表bridge捎废。
? ? ? (2)Transactions事務(wù)表擴展到Account笑窜,因此, Account表上的篩選也會對事務(wù)進行篩選登疗。
? ? ? (3)AccountCustomer表擴展到Account表排截, 但為了激活這種篩選,我們需要在計算中使用 AccountCustomer表作為一個篩選器參數(shù)辐益。使用雙向篩選器獲得了這種效果断傲。
? ? ? 在這里, 重要的部分是了解這個篩選器不是通過擴展表來移動的智政,而是通過加入篩選器實現(xiàn)的认罩。你可以通過使用"橋接表" 的老方法將篩選器從多端移動到一端來獲得類似的行為, 如下面的代碼所示:
CALCULATE( [SumOfAmount]续捂,AcccountCustomer )
其中猜年,SumOfAmount(元度量)的簡單定義為:
SumOfAmount:=SUM(Transactions[Amount] )
? ? ? 為什么說到篩選器,它們是相關(guān)連的疾忍?因為在這種情況下: 雙向篩選器引入的篩選器不能簡單地使用事實數(shù)據(jù)表中的ALL()來刪除乔外。
? ? ? 實際上,如果你編寫了一個新的度量值一罩, 用于從事務(wù)表中移除篩選器杨幼, 從而包含其擴展表 (包括Accounts帳戶), 則結(jié)果不是所期望的聂渊。請考慮以下公式:
SumOfAllAmount =
CALCULATE( [SumOfAmount]差购,ALL( Transactions ) )
? ? ? 它產(chǎn)生的結(jié)果與所之前度量的結(jié)果完全相同:
? ? ? 這里,從Transactions交易記錄表和Account帳戶表中正確地刪除了篩選器 (Account包含在擴展表的交易記錄中)汉嗽。但是欲逃, 橋接表上的篩選器是通過在擴展表之外工作的機制,這里是在Accounts表上運行的饼暑。因此稳析, 要從事實數(shù)據(jù)表中刪除該篩選器洗做, 當它來自bridge橋接表維度時, 也需要從 bridge 表中刪除該篩選器彰居。
? ? ? 實際上诚纸,下面的代碼會執(zhí)行正確刪除篩選器:
SumOfAllAmount :=
CALCULATE (
[SumOfAmount],ALL( AccountCustomer ) )
下圖顯示了該公式的正確結(jié)果(總是一個絕對值):
? ? ? 不需要從事實數(shù)據(jù)表或維度表中刪除篩選器陈惰, 因為它們的篩選器確實來自于橋表 (實際上畦徘,從Account表直接和橋表間接地連接方式)。在本例中抬闯, 從Account表或事務(wù)表中移除篩選器井辆, 證明是無用的。
? ? ? 正如你所看到的溶握,乍一看掘剪, 這與 DAX 處理篩選器似乎不一致, 但這只有當你不考慮擴展表的情況下是正確的奈虾。整個 DAX 關(guān)系模型是基于擴展表的, 當你掌握了以上概念后廉赔, 一切突然變得更有意義了肉微。
未完待續(xù)