مفهوم Row Context در DAX
این مقاله مفهوم Row Context در DAX را با استفاده از یک مدل مفهومی مبتنی بر نمایش تصویری توضیح میدهد.
Row Context دومین مفهوم بنیادی در نوشتن کد DAX است. در یک مقاله قبلی، اولین مفهوم – Filter Context – را با استفاده از یک رویکرد بصری معرفی کردیم. در این مقاله، از تجسم گرافیکی برای توضیح مفهوم Row Context استفاده میکنیم.
این مقاله دیدگاه متفاوتی از موضوعی که قبلاً در سایر مقالات مربوط به Row Context توضیح داده شده است، ارائه میدهد. برای دریافت بینش بیشتر در مورد این مفهوم مهم در DAX، مقالات دیگر را نیز مطالعه کنید.
یک ارجاع به ستون به Row Context نیاز دارد
هر زمان که در یک عبارت DAX از ارجاع به یک ستون استفاده کنید، به یک Row Context برای ارزیابی عبارت نیاز دارید. به عنوان مثال، عبارت DAX زیر را در نظر بگیرید:

فرمول، Quantity را در Net Price در جدول فروش ضرب میکند. به طور دقیقتر، فرمول مراحل زیر را انجام میدهد:
مقدار ستون Quantity را از ردیف جاری جدول فروش میگیرد.
مقدار ستون Net Price را از ردیف جاری جدول فروش میگیرد.
دو مقداری که در مراحل قبلی به دست آمدهاند را ضرب میکند.
هر ارجاع به ستون نیاز به یک “ردیف جاری” برای ارزیابی دارد. اما منظور از “ردیف جاری” چیست؟ در واقع، ما از “ردیف جاری” به عنوان یک اصطلاح عمومی برای شناسایی مفهومی خاص در DAX استفاده کردهایم: Row Context.
Row Context یک ردیف خاص از جدول را شناسایی میکند. به عنوان مثال، جدول فروش زیر را در نظر بگیرید.

ما میتوانیم Row Context برای ردیف دوم جدول فروش را با هایلایت کردن آن ردیف نمایش دهیم.

با این حال، ما میتوانیم Row Context را با استفاده از جدولی که تنها یک ردیف دارد نیز نمایش دهیم — همان ردیفی که توسط Row Context اشاره شده است.

این نوع نمایش بهویژه در توصیف Context Transition مفید است، موضوعی که در مقالهای در آینده توضیح داده خواهد شد.
چگونه یک Row Context بدست آوریم
یک Row Context میتواند با استفاده از تابع تکرارکننده (Iterator Function) در DAX برای تکرار یک جدول بدست آید. در DAX Guide، هر تابعی که یک جدول را تکرار میکند، برچسب Iterator برای جدولی که تکرار میشود و برچسب Row Context برای هر پارامتری که یک عبارت DAX را در Row Context بر روی جدول تکرار شده اجرا میکند، دارد. به عنوان مثال، اولین آرگومان تابع ADDCOLUMNS جدول تکرار شده است و ممکن است یک یا چند عبارت در Row Context برای هر ردیف از جدول تکرار شده ارزیابی شود.

شما میتوانید گروه Iterator را در DAX Guide فیلتر کنید تا فهرستی از تمام توابع تکرارکننده (Iterators) بدست آورید..

بنابراین، یک Iterator همیشه یک جدول را ردیف به ردیف اسکن میکند. Row Context همیشه دسترسی به تمام ردیف را فراهم میکند، حتی اگر عبارت ما تنها از چند ستون استفاده کند.

در حالی که موتور ممکن است اجرا را با توجه به ستونهای ارجاع شده در یک عبارت DAX بهینهسازی کند، از منظر مفهومی، ما به تمام ستونهای جدول تکرار شده دسترسی داریم. با این حال، Row Context هیچ هزینهای برای Materialization ندارد زیرا تنها موقعیت در یک جدول را نمایان میکند. دوباره میتوانیم Row Context را با جدولی که تمام ستونهای جدول اصلی را دارد و تنها یک ردیف دارد، نمایش دهیم، اما این جدول هیچ دادهای را تکثیر نمیکند – این فقط یک مدل مفهومی است که توضیح میدهد چگونه DAX کار میکند.
یک ستون محاسبهشده یک حالت خاص از Iterator است. زمانی که مدل تازهسازی میشود، موتور عبارت ستون محاسبهشده را برای هر ردیف جدول اجرا کرده و نتیجه آن را در یک ستون جداگانه ذخیره میکند. برخلاف Iterators که ردیفهای قابل مشاهده از طریق Filter Context را تکرار میکنند، ستونهای محاسبهشده در Filter Context خالی ارزیابی میشوند، بنابراین همیشه تمام ردیفهای جدول را تکرار میکنند.
Filter Context فیلتر میکند، Row Context تکرار میکند
زمانی که یک عبارت DAX اجرا میشود، معمولاً هم Filter Context و هم Row Context دخیل هستند. به عنوان مثال، تعریف زیر را برای اندازهگیری Sales Amount در نظر بگیرید:

SUMX یک Iterator در DAX است که آرگومان دوم را برای هر ردیف از جدول موجود در آرگومان اول اجرا میکند. ما میگوییم که SUMX جدول مشخصشده در آرگومان اول را تکرار میکند. Filter Context آن جدول را فیلتر میکند. سادهترین جدولی که میتوانیم استفاده کنیم، ارجاع به جدول Sales است. یک ارجاع جدول در DAX همیشه توسط Filter Context فیلتر میشود، بنابراین SUMX ردیفهای موجود در جدول Sales که در Filter Context قابل مشاهده هستند را تکرار میکند. به عنوان مثال، نمودار زیر این رفتار را نشان میدهد زمانی که ما یک فیلتر روی تاریخ 12 ژوئن 2024 اعمال میکنیم.

نام Sales برای شناسایی دو مفهوم مختلف استفاده میشود:
• در سمت چپ، ما جدول Sales در مدل semantic را داریم. وقتی در مورد “جدول مدل” صحبت میکنیم، منظورمان جدول فیزیکی در مدل semantic است که تمام ردیفها را شامل میشود و هرگونه فیلتر را نادیده میگیرد.
• در سمت راست، ما ارجاع به جدول Sales را داریم. یک ارجاع جدول در DAX همیشه توسط فیلترهای امنیتی و Filter Context فیلتر میشود. ارجاع جدول مانند یک “نما” از جدول مدل است که تنها ردیفهای “قابل مشاهده” را برمیگرداند. DAX نمیتواند فیلترهای امنیتی را نادیده بگیرد، در حالی که Filter Context میتواند با افزودن و حذف فیلترها از طریق توابع CALCULATE و CALCULATETABLE دستکاری شود.
عبارت SUMX این عملیاتها را اجرا میکند:
آرگومان اول را در Filter Context ارزیابی میکند.
برای هر ردیف در جدولی که در مرحله (1) بهدست آمده، آرگومان دوم را در Row Context مربوطه و همان Filter Context ارزیابی میکند.
Filter Context دیگر اهمیت ندارد اگر تنها از ارجاعات به ستونها در آرگومان دوم استفاده کنیم. با این حال، این موضوع میتواند در صورتی که عبارتهای دیگری داشته باشیم، مهم باشد. به عنوان مثال، اندازهگیری زیر مبلغ هر تراکنش را بر اساس عددی که توسط یک انتخاب فیلتر شده تقسیم میکند:

تابع SELECTEDVALUE انتخاب فعلی یک slicer را روی ستون Scale باز میگرداند، زیرا Filter Context هنوز در آن عبارت فعال است. کدی که نشان داده شده ایدهآل نیست، زیرا اگر عبارت به Row Context وابسته نباشد، ممکن است قبل از Iterator ارزیابی شود، که این وابستگی را به وضوح نشان میدهد که وجود ندارد:

در این مورد خاص، تقسیم باید خارج از SUMX قرار بگیرد. با این حال، هدف ما فقط این بود که توضیح دهیم Filter Context هنوز در عبارت ارزیابی شده در Row Context در Iterator در دسترس است. ما از این مثالها بهطور آموزشی استفاده کردیم و بهینهسازی کد هدف این مقاله نیست.
عبارت جدول Cardinality را تعریف میکند
Row Context تمام ردیفهایی را که توسط عبارت جدول ارائهشده به تابع Iterator بازگشت داده میشود، تکرار میکند. بنابراین، Cardinality یک تکرار توسط عبارت جدول تعریف میشود. به عنوان مثال، دو اندازهگیری زیر را در نظر بگیرید:

اندازهگیری Sales Amount Projection همان نتیجه را مانند Sales Amount برمیگرداند، زیرا تعداد ردیفهای تکرار شده (Cardinality) یکسان است. در واقع، حتی اگر متغیر SalesProjection تنها دو ستون داشته باشد، تعداد ردیفها یکسان است. از نظر عملکردی، تا زمانی که جدول Materialized نشده باشد، ما هزینهای برای تخصیص در حافظه ستونهای مدل غیرقابل استفاده که ممکن است ارجاع داده شوند، نمیپردازیم. با این حال، برای مقاصد این مقاله، میتوانیم این موضوع را نادیده بگیریم: آنچه مهم است این است که نتیجه SUMX به تعداد ردیفهای تکرار شده بستگی دارد و این تعداد یکسان است. تابع SELECTCOLUMNS Cardinality جدول تکرار شده را تغییر نمیدهد.
اندازهگیری Sales Amount Grouped نتیجه متفاوتی را باز میگرداند، زیرا تعداد ترکیبهای منحصر به فرد Quantity و Net Price در جدول Sales که توسط SUMMARIZE برگشت داده شده است را تکرار میکند. در واقع، SUMMARIZE میتواند تعداد کمتری از ردیفها از جدولی که در آرگومان اول ارائه شده است، برگرداند که معمولاً باعث میشود Cardinality نتیجه کوچکتر باشد. این Cardinality کوچکتر همانطور که در نتیجه مختلف مشاهده میشود، توضیح میدهد. تصویر زیر محتویات متغیرهای SalesProjection و SalesGrouped را که توسط دو اندازهگیری استفاده شدهاند، نشان میدهد.

Row Context میتواند به صورت بصری با استفاده از انتخاب یک ردیف در جدول یا با نمایش ردیف به عنوان یک جدول با تمام ستونها و تنها یک ردیف نمایش داده شود. این نوع نمایش برای زمانی که ما در مقالهای آینده به Context Transition میپردازیم، مفید خواهد بود.
Iterators یک Row Context بدست میآورند و Cardinality تکرار را از طریق عبارت جدول تکرار شده کنترل میکنند. در واقع، ارجاعهای ساده به جدول معمولاً تنها زیرمجموعهای از ردیفهای موجود در مدل را نشان میدهند به دلیل Filter Context. نمایش گرافیکی عبارت جدولی که به Iterator داده میشود، به درک Cardinality تکرار و ستونهای در دسترس در Row Context کمک میکند.
دیدگاهتان را بنویسید