嵌套DAX查询

时间:2016-11-08 07:36:18

标签: dax

我是一位经验丰富的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个月的平均值。

到目前为止,查询使用汇总来生成中间表 每月库存数量,即。

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

这完全符合预期。从此,应该能够平均 报告月份的库存。

此时,我将上面的查询包含在另一个汇总中 计算最终数字:

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]列的表。”

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

任何想法都赞赏。

编辑以响应Alejandro Zuleta:

亚历杭德罗,

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

库存历史记录是根据产品“列表”构建的。日期粒度是每月,每个列表都有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和offMarket月>的列表数量。 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

这很有效。挂断是......如何扩展这个以创建移动平均库存。

更新 弄清楚了。关键是从汇总切换到 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])  
) 

1 个答案:

答案 0 :(得分:0)

您可以使用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可视化中使用该度量。

enter image description here

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

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,你应该得到这个:

enter image description here

更新:

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

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

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

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

RESOURCE 1
RESOURCE 2

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

我已经使用计算列测试了这种方法,但它确实有用。

请告诉我这是否对您有所帮助。