简体   繁体   中英

DAX calculated column for related table with different grain

I want to create a TRUE/FALSE DAX calculated column on my sales table to filter for "Sales of Orders Containing Apples". Simplified schema:

Product Table:

| ProductKey | Product |
|------------|---------|
| 1          | Apples  |
| 2          | Milk    |

Sales table:

| SaleID | ProductKey | Sale Amount |
|--------|------------|-------|
| A      | 1          | £2    |
| B      | 2          | £4    |
| C      | 1          | £8    |
| C      | 2          | £16   |

I then apply a slicer/filter in Power BI/Power Pivot in Excel. The end result should be:

| SaleID | Sales of Orders Containing Apples |
|--------|------------|
| A      | £2         |
| C      | £24        |

I don't want to create a "Sales of Orders Containing Apples" measure. My real model has many measures and I want to slice/dice them all by this new attribute.

I can easily push this down to the data warehouse tier, but how is this achieved in DAX?

Sales = SUM ( 'Sales'[Sale Amount] )
Sales of orders containing selected product =
VAR OrdersInContext = VALUES ( 'Sales'[SaleID] )
RETURN
  CALCULATE (
    [Sales],
    ALL ( 'Product' ),
    OrdersInContext
  )

This is actually a lot more general than what you've asked for. Hopefully the definition of [Sales] is self-explanatory.

[Sales of orders containing selected product] first grabs a list of all 'Sales'[SaleID] values in the current context, which includes context from all dims, including 'Product'. In the sample case (screenshot below, from your question), the context is 'Product'[Product]="Apples", so our variable contains 'Sales'[SaleID] IN {"A", "C"}.

Next we use CALCULATE to manipulate the context within which to evaluate [Sales]. We clear all context on 'Product', but apply the context of 'Sales'[SaleID] stored in our variable, OrdersInContext.

Understanding that, and also understanding that the args to CALCULATE are evaluated independently, then intersected, we can shorten the definition to this:

Sales of orders containing selected product =
CALCULATE ( 
  [Sales],
  ALL ( 'Product' ),
  VALUES ( 'Sales'[SaleID] )
)

I show this second, just because I've found that most people find the style with the variable to be easier to understand. It is semantically equivalent to the first version.

And here it is in action:

按示例在表格视觉中进行度量

EDIT: Based on comments, we want to have this sort of slicer affect all measures for the fact table. I'm assuming the fact table interacts with more dims than just 'Product'. Either way, though, the following model would do it:

  • Tables
    • 'Product':: the product dimension shared
    • 'ProductSales':: a bridge table of unique pairs of (ProductKey, SaleID)
    • 'SaleIDs':: a table of only unique SaleIDs
    • 'Sales':: the original fact table shared
  • Relationships:
    • 'Product'[ProductKey] -1:N-> 'ProductSales'[ProductKey]
    • 'ProductSales'[SaleID] <-N:1-> 'SaleIDs'[SaleID]
    • 'SaleIDs'[SaleID] -1:N-> 'Sales'[SaleID]

See this in action below:

Model diagram: 模型图

And here a simple measure (no logic besides sum) showing correct aggregates in a report for you: 简单的汇总显示正确的N:N

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM