【问题标题】:Nested DAX Query嵌套 DAX 查询
【发布时间】:2023-04-11 09:00:02
【问题描述】:

我是一位经验丰富的 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 生成中间表 每月库存数量,即

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

这会产生一个中间表:

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

但是,这会返回错误:“无法识别包含 [inventory] ​​列的表。”

找不到引用中间表的方法。必须有另一种方式来构建它。

任何想法表示赞赏。


编辑以回应亚历杭德罗·祖莱塔:

亚历杭德罗,

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

库存历史是根据产品“列表”建立的。日期粒度是每月,每个列表都有一个 onMarket 月份和 offMarket 月份(月份按顺序编号)。列表还有其他属性 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 月份计算的,例如第 3 个月库存是 onMarket 月份 3(或空白)的列表数量。根据上表,库存如下:

库存

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 中定义/计算,然后在下面的查询中引用(在 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])  
) 

【问题讨论】:

    标签: dax


    【解决方案1】:

    您可以使用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 ()
    )
    

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

    但是,如果您需要获取表格,可以使用此表达式:

    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] )
    )
    

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

    更新:

    您的 DAX 表达式生成的库存表无法用于计算过去三个月的平均值。幸运的是,您使用的是支持计算表的 SSAS 2016。

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

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

    查看这些有关计算表创建的资源:

    RESOURCE 1
    RESOURCE 2

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

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

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

    【讨论】:

    • 谢谢亚历杭德罗。到达那里。请参阅对原始帖子的编辑。
    • @PaulEvans,您的输入表是使用最后一个表达式创建的吗?另外您使用的是什么版本的 SSAS?
    • 使用带有最新更新的 2016。最后一个表达式现在没有在进程中的任何地方使用。
    • @PaulEvans,我从你的问题中不明白的是你的输入表不是财政的,你使用一些表达式来产生它。你能和我分享一下这个表达式或财务列表表的基本示例吗?
    • 想我明白了。查看 GroupBy 函数的文档 (msdn.microsoft.com/en-us/library/mt163693.aspx)。它与总结非常相似。但是您可以将 GroupBy 的结果保存在一个变量中......然后在另一个 GroupBy 中访问该变量并获得“汇总”表达式(在我的情况下为库存)......虽然很复杂,但它可以工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 2016-12-25
    • 1970-01-01
    • 2019-07-18
    • 2021-01-29
    • 2020-08-01
    相关资源
    最近更新 更多