嵌套 DAX 查询

Nested DAX Query

我是一个经验丰富的 SQL 人……DAX 的新手。我正在尝试创建 生成移动平均库存的 DAX 查询。
库存计算的内部结构有点复杂,但是 希望这次讨论没有必要。

输入如下:

month   inventory
1        5
2        9
3        7
4        11

期望的输出是:

reportMonth average3MthInventory
3           7
4           9

也就是说,要报告的第 3 个月的平均库存是尾随的 1、2、3 个月的平均值 = (5+9+7) / 3 = 7 ... 第 4 个月是 第 2、3、4 个月的平均值。

到目前为止,查询使用 summarize 生成中间 table 每月库存数量,即

evaluate
filter(
  crossJoin(
    summarize(
      ...
        , reportMonths[month]   -- group by
      , "inventory", count(widgets[widgetID]) 
    ) -- end summarize
  ) -- end crossJoin
)  -- end filter

这会产生一个中间体 table:

reportMonths[month] actualMonths[month] [inventory] ... plus some other columns  
    3                   1                   5
    3                   2                   9
    3                   3                   7
    4                   2                   9
    4                   3                   7
    4                   4                   11

这完全符合预期。由此,应该可以平均 报告月份的库存。

此时,我将上面的查询包装在另一个 summarize 中以 计算最终数字:

evaluate
summarize(
  filter(
    crossJoin(
      summarize(
        ...
        , reportMonths[month]   -- group by
        , "inventory", count(widgets[widgetID]) 
      ) -- end summarize
    ) -- end crossJoin
  )  -- end filter
  , "month", reportMonths[month]
  , "avgInventory", average([inventory])
) -- summarize

但是,这 returns 一个错误:"Cannot identify the table that contains [inventory] column."

找不到引用中间体的方法table。必须有另一种方法来构造它。

任何想法表示赞赏。


编辑以回应 Alejandro Zuleta:

亚历杭德罗,

感谢您的快速回复。更多信息如下...

库存历史是根据产品 "listings" 建立的。日期粒度是每月,每个列表都有一个上市月份和场外月份(月份按顺序编号)。房源还有其他属性typeID、areaID等

listingID  onMarketMonth  offMarketMonth ... other attribs - typeID, etc.
101        1              2
103        1              6
105        2              2
106        2              
109        2              3
117        3              4
123        3              
124        3              9

库存是根据 onMarket 和 offMarket 月份计算的,例如in month 3 inventory 是上市月份 <= 3 且场外月份 > 3(或空白)的列表数量。根据以上table,库存如下:

库存

month   inventory   note: listings in inventory
1       2           101, 103
2       3           103, 106, 109
3       5           103, 106, 117, 123, 124
4       4           103, 106, 123, 124

...

需要能够报告一系列值,例如对于图表以及移动平均线。特定类型和区域的第 2 个月到第 6 个月的一系列示例代码为:

evaluate
summarize(
    filter(
        crossJoin(
            calculateTable(listings, listings[typeID] = 47)
            , filter(reportMonths, [month] >= 2 && [month] <= 6 )
        ) -- crossjoin
        , listings[onMarketMonth] <= reportMonths[month] && (or(listings[offMarketMonth] > reportMonths[month], isBlank(listings[offMarketMonth]))) -- join condition
    ) -- filter the join
    , reportMonths[month]
    , "inventory",count(listings[listingID])
) -- summarize

这行得通。挂断是......如何扩展它以创建移动平均库存。

更新 弄清楚了。关键是从 summarize 切换到 groupBy(https://msdn.microsoft.com/en-us/library/mt163693.aspx)。

请注意示例代码(下方)中的 [Total Sales] 在 VAR 的 GroupBy 中为 defined/calculated,然后在下方的查询中引用(在 Evaluate 的 GroupBy 中)。当我尝试使用 Summarize 进行类似操作时,出现错误。

DEFINE  
VAR SalesByCountryAndCategory =  
GROUPBY (  
Sales,   
Geography[Country],   
Product[Category],   
“Total Sales”, SUMX( CURRENTGROUP(), Sales[Price] * Sales[Qty])  
)  

Evaluate GROUPBY (  
SalesByCountryAndCategory,   
Geography[Country],   
 “Max Sales”, MAXX( CURRENTGROUP(), [Total Sales])  
) 

您可以使用 EARLIER 函数创建一个度量来获得所需的平均值。

average3MthInventory =
IF (
    MAX ( [month] ) > 2,
    CALCULATE (
        AVERAGE ( Inventory[inventory] ),
        FILTER (
            ALL ( Inventory[month] ),
            COUNTROWS (
                FILTER (
                    Inventory,
                    EARLIER ( [month] )
                        >= [month] - 2
                        && [month] >= EARLIER ( Inventory[month] )
                )
            )
        )
    ),
    BLANK ()
)

然后只需在您的数据透视表 table 或 Power BI 可视化中使用该度量。

但是如果你需要得到一个 table 你可以使用这个表达式:

EVALUATE
FILTER (
    SUMMARIZE (
        ADDCOLUMNS (
            ADDCOLUMNS (
                Inventory,
                "MinMonth", IF ( Inventory[month] > 2, Inventory[month] - 2, BLANK () )
            ),
            "average3MthInventory", IF (
                ISBLANK ( [MinMonth] ),
                BLANK (),
                CALCULATE (
                    AVERAGE ( Inventory[inventory] ),
                    FILTER (
                        Inventory,
                        [month] >= EARLIER ( [MinMonth] )
                            && [month] <= EARLIER ( [month] )
                    )
                )
            )
        ),
        [month],
        [average3MthInventory]
    ),
    NOT ISBLANK ( [average3MthInventory] )
)

假设你的输入 table 被称为 Inventory 你应该得到这个:

更新:

无法处理由您的 DAX 表达式生成的库存 table 以计算最近三个月的平均值。幸运的是,您使用的是支持计算 tables.

的 SSAS 2016

计算出的 table 完全可操作 table 由 DAX 表达式针对模型中的一个或多个 table 生成。

您必须使用每月生成库存的 DAX 表达式创建计算的 table。我建议您将其命名为 Inventory 以匹配我在上面发布的 DAX 查询以计算所需的平均值。

检查这些关于计算 table 创作的资源:

RESOURCE 1
RESOURCE 2

创建计算 table 后使用我的查询,您将看到过去三个月的平均值。

我已经使用计算列测试了这种方法并且它有效。

如果这对您有帮助,请告诉我。