RELATED คืนค่า scalar value (ค่าเดี่ยว) จากคอลัมน์ในตารางที่มีความสัมพันธ์แบบ many-to-one โดยอาศัย relationship ที่กำหนดไว้ในโมเดล ฟังก์ชันนี้ต้องการ row context และสามารถ traverse relationship chain ข้ามหลายขั้นได้ตราบใดที่ทุก relationship อยู่ในทิศทางเดียวกัน
=RELATED(<column>)
=RELATED(<column>)
| Argument | Type | Required | Default | Description |
|---|---|---|---|---|
| column | column | Yes | คอลัมน์ที่ต้องการดึงค่า ต้องอยู่ในตารางที่มี relationship แบบ many-to-one กับตารางปัจจุบัน (ตารางที่ดึงต้องอยู่ฝั่ง One) รูปแบบ: Table[Column] |
ดึงข้อมูลจากตารางมาสเตอร์ (Product, Customer, Category) มาเติมใน fact table (Sales, Orders) เช่น ดึงชื่อสินค้า หมวดหมู่ ต้นทุนต่อหน่วย ประเภทลูกค้า เพื่อให้สามารถใช้งานโดยตรงในตารางข้อมูล
ใช้ SUMX iterate แต่ละแถวของ Sales แล้วดึงต้นทุนต่อหน่วยจาก Product มาคูณกับจำนวนที่ขาย เพื่อคำนวณต้นทุนขายรวม (Cost of Goods Sold)
ใช้ RELATED ภายใน iterator function เช่น SUMX, AVERAGEX เพื่อดึงข้อมูลจากตารางที่เกี่ยวข้อง เช่น SUMX(Sales, Sales[Quantity] * RELATED(Product[Cost])) ซึ่งเป็น use case หลักของ RELATED ใน DAX
ดึงราคาล่าสุดจากตาราง Price List ที่มี relationship กับ Product มาใช้คำนวณรายได้หรือส่วนลดตามราคาปัจจุบัน
เดินผ่าน relationship หลายขั้น เช่น Sales → Product → Category → Division เพื่อดึงข้อมูลจาก Division โดยตรงโดยไม่ต้องผ่าน intermediate tables
Product Name = RELATED(Product[ProductName])Product Name = RELATED(Product[ProductName])
ได้ชื่อสินค้าที่ตรงกับ ProductKey ของแถวนั้น เช่น "Laptop Pro 15", "Wireless Mouse", "USB Cable"
Line Total = Sales[Quantity] * RELATED(Product[UnitPrice])Line Total = Sales[Quantity] * RELATED(Product[UnitPrice])
ได้ยอดขายของแต่ละแถว เช่น 5 * 299 = 1,495 บาท
Total COGS = SUMX( Sales, Sales[Quantity] * RELATED(Product[StandardCost]) )Total COGS =
SUMX(
Sales,
Sales[Quantity] * RELATED(Product[StandardCost])
)
ได้ต้นทุนขายรวม เช่น 125,450 บาท (ผลรวมของ Quantity × StandardCost ทุกแถวที่อยู่ใน filter context)
// ✅ วิธีถูก: กรองที่ Dimension Table โดยตรง (เร็ว + ถูกต้อง) Premium Sales Count = CALCULATE( COUNTROWS(Sales), Product[Category] = "Premium" ) // ❌ หลีกเลี่ยง…=// ✅ วิธีถูก: กรองที่ Dimension Table โดยตรง (เร็ว + ถูกต้อง)
Premium Sales Count =
CALCULATE(
COUNTROWS(Sales),
Product[Category] = "Premium"
)
// ❌ หลีกเลี่ยง: FILTER(Sales, RELATED(Product[Category]) = "Premium")
// ช้ามาก (วนลูปทุกแถวใน Fact Table) และอาจให้ผลผิด!
ได้จำนวนรายการขายที่เป็นสินค้าหมวด Premium เช่น 342 รายการ
Sales by Division = VAR SalesWithDivision = ADDCOLUMNS( Sales, "Division", RELATED(Category[DivisionName]) ) VAR FilteredSales = FILTER( SalesWithDivision, [Div…Sales by Division =
VAR SalesWithDivision =
ADDCOLUMNS(
Sales,
"Division", RELATED(Category[DivisionName])
)
VAR FilteredSales =
FILTER(
SalesWithDivision,
[Division] = "Consumer Electronics"
)
RETURN
SUMX(FilteredSales, Sales[Amount])
ได้ยอดขายของ Division "Consumer Electronics" เช่น 2,450,000 บาท
RELATED อาศัย relationship ที่กำหนดไว้ในโมเดล ทำงานเร็วกว่ามาก และใช้ได้เฉพาะทิศทาง many-to-one เท่านั้น
.
ส่วน LOOKUPVALUE ไม่ต้องการ relationship สามารถ lookup ด้วยเงื่อนไขใดก็ได้ (หลายคอลัมน์ หลายเงื่อนไข) แต่ช้ากว่าและต้องระวังกรณีพบหลายแถวที่ตรงกัน (จะเกิด error)
.
ส่วนตัวผมแนะนำให้ใช้ RELATED เสมอเมื่อมี relationship อยู่แล้วครับ ใช้ LOOKUPVALUE เฉพาะกรณีที่ไม่มี relationship จริงๆ
ความแตกต่างหลักคือทิศทางและชนิดข้อมูลที่คืนกลับครับ
.
RELATED ใช้ในตารางฝั่ง Many → ดึงค่าเดี่ยวจากตารางฝั่ง One (คืนค่า scalar) ส่วน RELATEDTABLE ใช้ในตารางฝั่ง One → ดึงตารางจากฝั่ง Many (คืนค่า table ที่มีหลายแถว)
.
ตัวอย่างง่ายๆ ใน Sales ใช้ RELATED(Product[ProductName]) จะได้ชื่อสินค้า 1 ชื่อ แต่ใน Product ใช้ RELATEDTABLE(Sales) จะได้ตารางที่มีทุกแถวของ Sales ที่ขายสินค้าชิ้นนั้น
ใช้ได้ครับ แต่ต้องใช้ภายใน iterator function เช่น SUMX, FILTER ที่สร้าง row context ให้
.
เพราะ RELATED ต้องการ row context ในการทำงาน ไม่สามารถใช้ RELATED โดยตรงใน measure ที่มีแต่ filter context ได้ (จะเกิด error ทันที)
.
ตัวอย่าง: SUMX(Sales, Sales[Quantity] * RELATED(Product[UnitPrice])) ทำงานได้ แต่ RELATED(Product[UnitPrice]) เฉพาะๆ ใน measure ทำงานไม่ได้นะครับ
ดูที่ลูกศรของ relationship line ใน Model view ครับ ลูกศรจะชี้จากตารางฝั่ง Many ไปยังตารางฝั่ง One
.
เช่น Sales → Product (Sales คือ Many, Product คือ One) หรือดูที่ multiplicity indicator (1 กับ *) เช่น Sales (*) → Product (1) หมายความว่า Sales มีหลายแถวต่อ 1 Product
.
ดังนั้นใช้ RELATED ใน Sales ได้ แต่ใช้ใน Product ไม่ได้ (ต้องใช้ RELATEDTABLE แทน)
RELATED ทำงานได้ทั้งสองทิศทางถ้า relationship ตั้งค่าเป็น bidirectional (Both) ครับ
.
แต่ส่วนตัวผมแนะนำให้ใช้อย่างระมัดระวัง เพราะ bidirectional relationship อาจทำให้เกิด ambiguity และ performance issues ใน DAX ได้
.
ควรใช้ single direction (One) เสมอเมื่อเป็นไปได้ และใช้ CROSSFILTER หรือ USERELATIONSHIP ใน CALCULATE เมื่อต้องการเปลี่ยนทิศทางชั่วคราว
ไม่ได้ครับ RELATED ต้องการ regular relationship เท่านั้น ไม่สามารถทำงานกับ limited relationship ได้
.
(เช่น relationship ที่ข้าม DirectQuery boundary หรือ composite model boundary)
.
หากต้องการ traverse limited relationship ให้ใช้ LOOKUPVALUE แทน หรือใช้ RELATEDTABLE ซึ่งสามารถข้าม limited relationship ได้ผ่าน context transition
มีผลกระทบต่อขนาดโมเดลและหน่วยความจำครับ แต่ไม่ค่อยกระทบต่อ query performance มากนัก
.
เพราะ calculated column ถูก evaluate ครั้งเดียวเมื่อ refresh ข้อมูล แต่ผลลัพธ์จะเก็บไว้ในโมเดล ทำให้เพิ่มขนาดไฟล์และ RAM ที่ใช้
.
หาก calculated column มีจำนวนมาก ส่วนตัวผมแนะนำให้ทำ data transformation ใน Power Query แทน หรือใช้ใน measure แทนเมื่อเป็นไปได้ (measure คำนวณตอน query time ไม่เพิ่มขนาดโมเดล)
RELATED เป็นฟังก์ชันพื้นฐานที่สำคัญใน DAX สำหรับการดึงค่าจากตารางที่มีความสัมพันธ์แบบ many-to-one (จากตารางข้อมูลฝั่ง “Many” ไปยังตารางมาสเตอร์ฝั่ง “One”) โดยอาศัยความสัมพันธ์ (relationship) ที่ถูกกำหนดไว้ในโมเดลข้อมูล ฟังก์ชันนี้จะคืนค่าเป็น scalar value (ค่าเดี่ยว) จากคอลัมน์ที่ระบุในตารางที่เกี่ยวข้อง ซึ่งเป็นเครื่องมือหลักที่ใช้ใน calculated column และ iterator function เพื่อ enrich ข้อมูลจากตารางมาสเตอร์มาใช้งาน
การทำงานของ RELATED ต้องอาศัย row context (บริบทของแถว) ซึ่งหมายความว่าฟังก์ชันนี้ทำงานได้ใน calculated column หรือภายใน iterator function เช่น SUMX, FILTER เท่านั้น เพราะต้องมีแถวปัจจุบันที่ชัดเจนเพื่อให้ DAX สามารถ traverse (เดินตาม) relationship ไปยังตารางที่เกี่ยวข้อง และดึงค่าที่ตรงกับ foreign key ของแถวปัจจุบันกลับมาได้อย่างถูกต้อง ตัวอย่างเช่น ในตาราง Sales ที่มี ProductKey คุณสามารถใช้ RELATED(Product[ProductName]) เพื่อดึงชื่อสินค้าที่ตรงกับ ProductKey ของแถวนั้นๆ มาใช้งานได้
จุดสำคัญที่ต้องเข้าใจคือ row context does not propagate through relationships โดยอัตโนมัติ นั่นคือเมื่อคุณกำลัง iterate แต่ละแถวของตาราง Sales คุณไม่สามารถ reference คอลัมน์จากตาราง Product ได้โดยตรง (เช่น Product[ProductName]) เพราะ row context ไม่ได้ “ไหล” ผ่าน relationship ไปยังตารางอื่น RELATED จึงเป็นเครื่องมือที่ทำหน้าที่ เปิดช่องทาง ให้คุณสามารถเข้าถึงข้อมูลในตารางที่เกี่ยวข้องได้ โดยอาศัยการเดินตาม relationship chain จาก foreign key ในตารางปัจจุบันไปยัง primary key ในตารางเป้าหมาย
RELATED สามารถ traverse relationship chain ข้ามหลายขั้นได้ ตราบใดที่ทุก relationship อยู่ในทิศทาง many-to-one เดียวกัน ตัวอย่างเช่น หากมีตาราง Sales → Product → Category คุณสามารถใช้ RELATED(Category[CategoryName]) ใน calculated column ของตาราง Sales ได้โดยตรง โดย DAX จะเดินผ่าน Sales → Product → Category โดยอัตโนมัติ แต่หากมี relationship ใดขาดหายหรือมี direction ผิดทิศทาง RELATED จะเกิด error ทันที
ความแตกต่างหลักคือ ทิศทางการ traverse relationship และ ชนิดของค่าที่คืนกลับ:
RELATEDTABLE เป็น alias ของ CALCULATETABLE ที่ทำ context transition และสามารถข้าม limited relationship ได้ ในขณะที่ RELATED ต้องการ regular relationship เท่านั้น (ไม่สามารถทำงานข้าม DirectQuery boundary ที่เป็น limited relationship ได้)
Calculated Column: ใช้กรณีที่ต้องการ enrich ข้อมูลถาวรในตาราง เช่น เพิ่มคอลัมน์ชื่อสินค้า, หมวดหมู่, ต้นทุนต่อหน่วย โดย RELATED จะ evaluate ครั้งเดียวเมื่อโหลดข้อมูล และเก็บผลลัพธ์ไว้ในโมเดล ข้อเสียคือจะเพิ่มขนาดไฟล์โมเดล หากมี calculated column จำนวนมากควรพิจารณาทำใน ETL หรือใช้ใน measure แทน
Iterator Function (SUMX, FILTER): ใช้กรณีที่ต้องการคำนวณแบบ dynamic ใน measure เช่น คำนวณต้นทุนขาย (COGS) โดยใช้ SUMX วน Sales แต่ละแถว แล้วดึงต้นทุนต่อหน่วยจาก Product มาคูณกับจำนวน วิธีนี้ไม่เพิ่มขนาดโมเดล และสามารถตอบสนอง filter context ได้อย่างยืดหยุ่น แนะนำให้ใช้วิธีนี้มากกว่า calculated column เมื่อเป็นไปได้
⚠️ Calculated column ที่ใช้ RELATED มาก: หาก calculated column มีจำนวนมากและใช้ RELATED หลายครั้ง จะเพิ่มขนาดโมเดลและหน่วยความจำที่ใช้ ควรพิจารณาทำการ enrich ข้อมูลใน Power Query หรือใช้ใน measure แทน
⚠️ Limited Relationship: RELATED ไม่สามารถทำงานกับ limited relationship ได้ (เช่น relationship ที่ข้าม DirectQuery boundary) ถ้าต้องการ traverse limited relationship ให้ใช้ LOOKUPVALUE หรือ RELATEDTABLE แทน
💡 RELATED vs LOOKUPVALUE: RELATED เร็วกว่า LOOKUPVALUE มาก เพราะอาศัย relationship ที่ถูก optimize ไว้แล้วในโมเดล ใช้ RELATED เสมอเมื่อมี relationship อยู่แล้ว และใช้ LOOKUPVALUE เฉพาะกรณีที่ไม่มี relationship หรือต้องการ lookup ด้วยเงื่อนไขที่ซับซ้อนกว่า