【问题标题】:What is the difference between cube, rollup and groupBy operators?多维数据集、汇总和分组运算符之间有什么区别?
【发布时间】:2016-10-24 19:41:06
【问题描述】:

问题几乎在标题中。我找不到任何关于差异的详细文档。

我确实注意到了不同之处,因为在交换 cube 和 groupBy 函数调用时,我得到了不同的结果。我注意到,对于使用“立方体”的结果,我经常分组的表达式中有很多空值。

【问题讨论】:

    标签: sql apache-spark apache-spark-sql cube rollup


    【解决方案1】:
    1. 如果您不希望 null 首先使用以下示例将其删除 dfwithoutnull=df.na.drop("all",seq(col name 1,col name 2)) 上面的表达式将从原始数据帧中删除 null

    2.group by 你知道我猜。

    3.rollup 和cube 是GROUPING SET 运算符。 Roll-up是一个多维聚合和分层处理元素

    在多维数据集中而不是分层处理元素,多维数据集在所有维度上做同样的事情。 可以试试 grouping_id 来了解抽象的层次

    【讨论】:

      【解决方案2】:

      它们的工作方式不同。 groupBy 完全等同于标准 SQL 中的 GROUP BY 子句。换句话说

      table.groupBy($"foo", $"bar")
      

      相当于:

      SELECT foo, bar, [agg-expressions] FROM table GROUP BY foo, bar
      

      cube 相当于 CUBE 扩展为 GROUP BY。它采用列列表并将聚合表达式应用于分组列的所有可能的组合。假设您有这样的数据:

      val df = Seq(("foo", 1L), ("foo", 2L), ("bar", 2L), ("bar", 2L)).toDF("x", "y")
      
      df.show
      
      // +---+---+
      // |  x|  y|
      // +---+---+
      // |foo|  1|
      // |foo|  2|
      // |bar|  2|
      // |bar|  2|
      // +---+---+
      

      然后你计算 cube(x, y) 并将 count 作为聚合:

      df.cube($"x", $"y").count.show
      
      // +----+----+-----+     
      // |   x|   y|count|
      // +----+----+-----+
      // |null|   1|    1|   <- count of records where y = 1
      // |null|   2|    3|   <- count of records where y = 2
      // | foo|null|    2|   <- count of records where x = foo
      // | bar|   2|    2|   <- count of records where x = bar AND y = 2
      // | foo|   1|    1|   <- count of records where x = foo AND y = 1
      // | foo|   2|    1|   <- count of records where x = foo AND y = 2
      // |null|null|    4|   <- total count of records
      // | bar|null|    2|   <- count of records where x = bar
      // +----+----+-----+
      

      cube 类似的函数是rollup,它从左到右计算分层小计:

      df.rollup($"x", $"y").count.show
      // +----+----+-----+
      // |   x|   y|count|
      // +----+----+-----+
      // | foo|null|    2|   <- count where x is fixed to foo
      // | bar|   2|    2|   <- count where x is fixed to bar and y is fixed to  2
      // | foo|   1|    1|   ...
      // | foo|   2|    1|   ...
      // |null|null|    4|   <- count where no column is fixed
      // | bar|null|    2|   <- count where x is fixed to bar
      // +----+----+-----+
      

      为了比较,让我们看看普通groupBy的结果:

      df.groupBy($"x", $"y").count.show
      
      // +---+---+-----+
      // |  x|  y|count|
      // +---+---+-----+
      // |foo|  1|    1|   <- this is identical to x = foo AND y = 1 in CUBE or ROLLUP
      // |foo|  2|    1|   <- this is identical to x = foo AND y = 2 in CUBE or ROLLUP
      // |bar|  2|    2|   <- this is identical to x = bar AND y = 2 in CUBE or ROLLUP
      // +---+---+-----+
      

      总结一下:

      • 当使用纯 GROUP BY 时,每一行在其对应的摘要中只包含一次。
      • 对于GROUP BY CUBE(..),每一行都包含在它所代表的每个级别组合的摘要中,包括通配符。从逻辑上讲,上面显示的内容等价于这样的内容(假设我们可以使用NULL 占位符):

        SELECT NULL, NULL, COUNT(*) FROM table
        UNION ALL
        SELECT x,    NULL, COUNT(*) FROM table GROUP BY x
        UNION ALL
        SELECT NULL, y,    COUNT(*) FROM table GROUP BY y
        UNION ALL
        SELECT x,    y,    COUNT(*) FROM table GROUP BY x, y
        
      • GROUP BY ROLLUP(...) 类似于 CUBE,但通过从左到右填充列来分层工作。

        SELECT NULL, NULL, COUNT(*) FROM table
        UNION ALL
        SELECT x,    NULL, COUNT(*) FROM table GROUP BY x
        UNION ALL
        SELECT x,    y,    COUNT(*) FROM table GROUP BY x, y
        

      ROLLUPCUBE 来自数据仓库扩展,因此如果您想更好地了解其工作原理,还可以查看您最喜欢的 RDMBS 的文档。例如 PostgreSQL 在 9.5 和 these are relatively well documented 中都引入了。

      【讨论】:

      • group by rollup 查询中不会有 SELECT y, NULL, COUNT(*) FROM table GROUP BY y 吗?
      • @Sam,因为rollup表示给定的表达式列表和列表的所有前缀包括空列表,cube表示给定的列表和所有的它可能的子集
      猜你喜欢
      • 2013-08-26
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 2014-09-21
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 2019-07-09
      相关资源
      最近更新 更多