代码之家  ›  专栏  ›  技术社区  ›  Przemyslaw Remin

过滤摘要栏

  •  0
  • Przemyslaw Remin  · 技术社区  · 4 年前

    如何为构建筛选表 SUMMARIZECOLUMNS 功能?

    这个 SUMMARIZECOLUMNS 具有以下模式:

    SUMMARIZECOLUMNS( 
        ColumnName1, ...
        ColumnNameN,
        FilterTable1,     -- my question concerns this line
        FilterTableN, 
        Name1, [measure1], 
        NameN, [measure2], 
    )
    

    我已经检查了以下3种模式是否有效。它们返回了相同的结果,至少对于我使用的简单样本数据是这样。

    SUMMARIZECOLUMNS (
        T[col],
        FILTER( T, T[col] = "red" ) 
    )
    
    SUMMARIZECOLUMNS (
        T[col],
        CALCULATETABLE( T, T[col] = "red" ) 
    )
    
    SUMMARIZECOLUMNS (
        T[col],
        CALCULATETABLE ( T, KEEPFILTERS ( T[col] = "red" ) )
    )
    

    这些模式中有哪一个比另一个优越吗?

    参考: https://www.sqlbi.com/articles/introducing-summarizecolumns/

    更新

    我对包含查询计划分析的答案感兴趣 或链接到可靠来源。如果您能提及,我将不胜感激 在对以下列进行分组时使用SUMMARIZECOLUMNS函数 多张桌子。

    0 回复  |  直到 4 年前
        1
  •  5
  •   Dave Markle    4 年前

    您还可以使用VAR按照PowerBI的方式构建它们:

    VAR  __MyFilterTable = FILTER( T, T[col] = "red" ) 
    
    RETURN
    SUMMARIZECOLUMNS (
        T[col],
        __MyFilterTable
    )
    

    哪种方法更有效取决于过滤的复杂性,因此不一定有“一刀切”的规则。对于一个简单的表级过滤器,只需过滤器就足够了。我提醒你,过滤整个表T的第1行是个坏主意。只过滤单个列的性能要高得多。当你过滤整个表时,DAX会在内存中物化整个表,而下面只物化T[col]的一个值:

    VAR  __MyFilterTable = FILTER( ALL(T[col]), T[col] = "red" ) // This is better.
    
    RETURN
    SUMMARIZECOLUMNS (
        T[col],
        __MyFilterTable
    )
    

    从概念上讲,你甚至可以做得更好。你基本上可以告诉DAX,“我知道这是一个值,所以甚至不要在表中查找它。只需为我创建一个表,并将其视为我过滤了它。就像这样:

    VAR  __MyFilterTable = TREATAS ({"red"}, T[col] )
    
    RETURN
    SUMMARIZECOLUMNS (
        T[col],
        __MyFilterTable
    )
    

    同样,这是PowerBI在执行过滤器时使用的模式。

    顺便说一句,在顶部创建过滤表与使用SUMMARIZECOLUMNS()内联创建过滤表在速度上没有任何区别。避免使用CALCULTETABLE(),就像你在这里通常做的那样。

    你也可以这样做,尽管你通常不太可能看到速度的提高:

    CALCULATETABLE(
        SUMMARIZECOLUMNS (
            T[col]
        ),
        KEEPFILTERS(T[col] = "red")
    )