<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          徹底理解 PowerBI DAX 函數(shù) EARLIER

          共 4848字,需瀏覽 10分鐘

           ·

          2021-02-02 21:33

          很多業(yè)務(wù)背景的伙伴進(jìn)入 DAX 世界后,第一個(gè)攔路虎就是 EARLIER。

          因?yàn)檫@是我們業(yè)務(wù)人員平時(shí)不用的思維邏輯:迭代。

          迭代,是區(qū)分文科與理科;業(yè)務(wù)與 IT 的標(biāo)志性思維邏輯。

          迭代,在傳統(tǒng)的編程領(lǐng)域又叫循環(huán),迭代是循環(huán)的等價(jià)。

          本文讓您徹底理解 EARLIER 以及迭代,不管你是什么背景。

          什么叫迭代

          迭代,簡(jiǎn)單說就是數(shù)數(shù);而精確說,就是:對(duì)已知集合中元素的遍歷。

          例如:我們有一個(gè)集合:{ 1, ... , 10 },對(duì)這個(gè)集合的遍歷,就是挨個(gè)看一遍。

          例如:我們有一個(gè)集合:{ 蘋果,鴨梨,橘子,香蕉 },對(duì)這個(gè)集合的遍歷,就是挨個(gè)看一遍。

          從這個(gè)意義上來說,迭代本身是很傻的,光看不做事。

          所以,伴隨著著迭代,一般都得做點(diǎn)壞事,不然不白迭代了,白看了。

          理解 DAX 中的 SUM

          在 DAX 中,SUM 的用法如下:

          [Sales] := SUM( Order[Amount] )

          它完全等價(jià)于:

          [Sales] := SUMX( Order , Order[Amount] )

          其含義為:

          對(duì) Order 表進(jìn)行迭代,并把遍歷到的數(shù)據(jù)行的 [Amount] 列的值提取出來全部加起來。

          從邏輯上來講,SUMX 有兩個(gè)重要?jiǎng)幼鳎?/p>

          • 在遍歷的元素的時(shí)候提取元素

          • 最后在遍歷完成時(shí)全部加起來

          注意:實(shí)際 DAX 引擎的物理執(zhí)行可能與此不同,但邏輯上可以這么理解。

          SUMX 中隱藏的迭代器

          SUMX 的執(zhí)行如下:

          SUMX( Order , Order[Amount] ) = 

          【 迭代開始{ 】

          row1 , 取出當(dāng)前行 [Amount]
          row2 , 取出當(dāng)前行 [Amount]
          row3 , 取出當(dāng)前行 [Amount]
          row4 ,取出當(dāng)前行 [Amount]
          ...
          【 } 迭代完成 】

          【【將所有取出的值相加并返回。】】

          其中:

          • 【迭代開始{ ... } 迭代完成】為隱藏的內(nèi)置迭代器

          • 【【..】】為迭代完后的內(nèi)置操作

          由于這兩步邏輯被 SUMX 隱藏了,很多業(yè)務(wù)背景的伙伴就不得理解:

          • 到底迭代器長成啥樣

          • 迭代里面發(fā)生了啥

          • 迭代完了發(fā)生了啥

          以上圖示為了更加形象地說明這個(gè)過程。

          迭代中的行上下文

          在 DAX 中,表可以是這樣的:

          { 1 , 2 , 3 }

          // 或者這么寫
          {
          1,
          2,
          3
          }

          這會(huì)得到:

          由于沒有給這個(gè)表的列起名字,這一列默認(rèn)叫 Value,那么來考察:

              SUMX (
          {
          1,
          2,
          3
          },
          [Value]
          )

          可以得到:

          在迭代中,可以從[Value]列取出值必須要能鎖定當(dāng)前的行,就是行上下文。

          也就是說,在迭代中,遍歷的每個(gè)元素就是行上下文,在行中可以取出列值,否則無法做到。

          注意

          很多初學(xué)者問:什么叫行上下文?其實(shí)更應(yīng)該換一個(gè)問法。

          一個(gè)更好的問題應(yīng)該是:

          在迭代一個(gè)集合的時(shí)候,DAX 是否有什么機(jī)制來讓用戶可以操作正在遍歷的元素?

          回答:

          DAX 有這種機(jī)制,并起名叫:行上下文,用來取出迭代中正在遍歷的元素。

          這很好,正如我們的預(yù)期。

          進(jìn)入燒腦階段開始。

          多層迭代 - 同名覆蓋

          請(qǐng)考察:

              SUMX (
          { 1, 3 },
          SUMX ( { 1, 2 } , [Value] * [Value] )
          )

          對(duì)于 { 1 , 3 } 來說,它有一列叫:[Value];

          對(duì)于 { 1 , 2 } 來說,它也有一列叫:[Value]。

          注意

          由于兩個(gè) SUMX 的出現(xiàn),也就出現(xiàn)了兩套嵌套的迭代器,這就形成了在 迭代 中的 迭代,也就是:多層迭代

          那么,此處的 [Value] * [Value] 到底指的是:誰的[Value] * 誰的[Value] 呢?

          其執(zhí)行細(xì)節(jié)如下:

          [Value]    [Value]
          1
          1 1 * 1
          2 2 * 2
          3
          1 1 * 1
          2 2 * 2

          這里用 TAB 的縮進(jìn)表示了不同的層次。

          請(qǐng)仔細(xì)觀察上述內(nèi)容,理解其規(guī)律。可以知道:[Value] 指的是 { 1, 2 } ,這是合理和自然的。也就是說:

          迭代     迭代
          [Value] [Value]
          1
          1 當(dāng)前行上下文[Value] 1 * 當(dāng)前行上下文[Value] 1 = 1
          2 當(dāng)前行上下文[Value] 2 * 當(dāng)前行上下文[Value] 2 = 4
          3
          1 當(dāng)前行上下文[Value] 1 * 當(dāng)前行上下文[Value] 1 = 1
          2 當(dāng)前行上下文[Value] 2 * 當(dāng)前行上下文[Value] 2 = 4

          是實(shí)際執(zhí)行的邏輯結(jié)構(gòu)。其結(jié)果如下:

          不難發(fā)現(xiàn),其結(jié)果是預(yù)期的,同時(shí)發(fā)現(xiàn):

          根本沒有用到 { 1 , 3 } 以及其中的元素,在更復(fù)雜的場(chǎng)景中,業(yè)務(wù)上需要:在內(nèi)層可以訪問到外層同名的列。

          多層迭代 - 內(nèi)外跨層穿越

          考察上面已經(jīng)有的結(jié)構(gòu):

          迭代     迭代
          [Value] [Value]
          1
          1 當(dāng)前行上下文[Value] 1 * 當(dāng)前行上下文[Value] 1 = 1
          2 當(dāng)前行上下文[Value] 2 * 當(dāng)前行上下文[Value] 2 = 4
          3
          1 當(dāng)前行上下文[Value] 1 * 當(dāng)前行上下文[Value] 1 = 1
          2 當(dāng)前行上下文[Value] 2 * 當(dāng)前行上下文[Value] 2 = 4

          如果我們希望這樣呢:

          迭代     迭代
          [Value] [Value]
          1
          1 當(dāng)前行上下文[Value] 1 * 上一層迭代的行上下文中的[Value] 1 = 1
          2 當(dāng)前行上下文[Value] 2 * 上一層迭代的行上下文中的[Value] 1 = 2
          3
          1 當(dāng)前行上下文[Value] 1 * 上一層迭代的行上下文中的[Value] 3 = 3
          2 當(dāng)前行上下文[Value] 2 * 上一層迭代的行上下文中的[Value] 3 = 6

          在 DAX 中就需要這樣編寫,如下:

          可以看出:

          EARLIER( C , X ) 的精確語義是:

          上 X 層迭代的行上下文中的列 C 的值。

          若 X = 1,可以忽略,將 EARLIER( [Value] , 1 ) 簡(jiǎn)寫為 EARLIER( [Value] )。

          那么,函數(shù) EARLIER 就起到了跨層穿越的效果。

          多層迭代 - 默認(rèn)穿越

          在理解上述內(nèi)容后,來看一道測(cè)試題吧:

              VAR A = SELECTCOLUMNS( { 1, 3 } , "A" , [Value] )
          VAR B = SELECTCOLUMNS( { 1, 2 } , "B" , [Value] )
          RETURN SUMX (
          A,
          // 這里需要放一句話
          )

          這里需要放一句話,請(qǐng)選擇:

          • 選項(xiàng) 1 - SUMX ( B , [B] * [A] ),且選項(xiàng) 2 語法錯(cuò)誤

          • 選項(xiàng) 2 - SUMX ( B , [B] * EARLIER( [A] ) ),且選項(xiàng) 1 語法錯(cuò)誤

          在不做實(shí)驗(yàn)的情況下,請(qǐng)選擇 A 還是 B 呢?

          如果選項(xiàng) 1 對(duì),那么說明:[A] 的訪問,由于無同名列的遮擋,不需要跨層,也不能跨層,所以不能用 EARLIER;

          如果選項(xiàng) 2 對(duì),那么說明:[A] 的訪問,雖然無同名列的遮擋,由于不同層,必須要跨層,所以必須用 EARLIER。

          而實(shí)際的結(jié)果是:

          在這個(gè)場(chǎng)景中,SUMX ( B , [B] * [A] ) 與 SUMX ( B , [B] * EARLIER( [A] ) ) 完全一致。

          結(jié)果如下:

          以及:

          也就是說,在這個(gè)場(chǎng)景下的 SUMX ( B , [B] * [A] ) ,如下:

             迭代     迭代
          [A] [B]
          1
          1 當(dāng)前行上下文[B] 1 * 當(dāng)前行上下文[A] 1 = 1
          2 當(dāng)前行上下文[B] 2 * 當(dāng)前行上下文[A] 1 = 2
          3
          1 當(dāng)前行上下文[B] 1 * 當(dāng)前行上下文[A] 3 = 3
          2 當(dāng)前行上下文[B] 2 * 當(dāng)前行上下文[A] 3 = 6

          完全等價(jià)于這個(gè)場(chǎng)景下的 SUMX ( B , [B] * EARLIER( [A] ) ) ,如下:

             迭代     迭代
          [A] [B]
          1
          1 當(dāng)前行上下文[B] 1 * 上一層迭代的行上下文中的[A] 1 = 1
          2 當(dāng)前行上下文[B] 2 * 上一層迭代的行上下文中的[A] 1 = 2
          3
          1 當(dāng)前行上下文[B] 1 * 上一層迭代的行上下文中的[A] 3 = 3
          2 當(dāng)前行上下文[B] 2 * 上一層迭代的行上下文中的[A] 3 = 6

          這讓我們得到以下結(jié)論:

          • DAX 提供了迭代中需要訪問當(dāng)前元素的機(jī)制,叫做:行上下文。

          • 迭代是可以嵌套的。

          • 在嵌套的迭代中,內(nèi)層可以訪問外層。

            • 若列不遮擋,也就是使用不同層的不同名列,則可以直接訪問,也可以使用 EARLIER 顯式指定要訪問的相對(duì)第 X 外層。

            • 若列有遮擋,也就是使用不同層的相同名列,則默認(rèn)使用內(nèi)層,這必須使用 EARLIER 顯式指定要訪問的相對(duì)第 X 外層。

          • 不論是內(nèi)層或者外層,都處于(或有自己)相應(yīng)的行上下文。

          總結(jié)

          要理解 EARLIER 就要知道行上下文;

          要理解 行上下文就要知道迭代;

          迭代是遍歷大量元素的邏輯手段;

          在數(shù)據(jù)模型中,大量元素以邏輯行的形式存在于表中;

          遍歷表的元素,就是表的行;

          從正在遍歷(迭代)的行中取出值需要一個(gè)機(jī)制來框住當(dāng)前行,稱為:行上下文;

          迭代是可以多層嵌套的;

          從更內(nèi)層迭代中的行上下文可以訪問相對(duì)外層迭代中的行上下文,這時(shí)使用 EARLIER 即可。

          EARLIER,顧名思義,更早的,意思為更早創(chuàng)建出的行上下文。

          用 EARLIER 實(shí)現(xiàn)的這種牛叉特性可以起一個(gè)牛叉的名字:跨層穿越

          BI佐羅講解的 DAX 是從本質(zhì)層面進(jìn)行的,本質(zhì)不表示大而全,而是邏輯的完備和簡(jiǎn)潔,學(xué)習(xí) EARLIER 竟不需要任何一個(gè)業(yè)務(wù)表,因?yàn)榛緮?shù)學(xué)知識(shí)足以。學(xué)習(xí)《BI真經(jīng)》,窺見更多本質(zhì)。

          讓數(shù)據(jù)真正成為你的力量

          Create value?through?simple and?easy?with fun?by PowerBI

          Excel BI?|?DAX Pro?|?DAX?權(quán)威指南?|?線下VIP學(xué)習(xí)

          掃碼與PBI精英一起學(xué)習(xí),驗(yàn)證碼:data2021

          PowerBI MVP 帶你正確而高效地學(xué)習(xí) PowerBI
          點(diǎn)擊“閱讀原文”,即刻開始

          瀏覽 146
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产髙清无码播放 | 逼操| 中文字字幕在线中文 | 野外体内射精视频 | 爱草逼爱草逼爱草逼爱草逼爱草逼爱草逼爱草逼 |