【问题标题】:How to GROUPING SETS as operator/method on Dataset?如何将集合分组为数据集上的运算符/方法?
【发布时间】:2017-04-16 20:39:36
【问题描述】:

spark scala 中没有函数级别的 grouping_sets 支持吗?

我不知道这个补丁是否应用于 master https://github.com/apache/spark/pull/5080

我想通过 scala dataframe api 做这种查询。

GROUP BY expression list GROUPING SETS(expression list2)

cuberollup functions 在 Dataset API 中可用,但找不到分组集。为什么?

【问题讨论】:

    标签: apache-spark dataframe apache-spark-sql


    【解决方案1】:

    我想通过 scala dataframe api 做这种查询。

    tl;dr 在 Spark 2.1.0 之前这是不可能的。目前没有计划将此类运算符添加到 Dataset API。

    Spark SQL 支持以下所谓的多维聚合运算符

    • rollup运营商
    • cube运营商
    • GROUPING SETS 子句(仅在 SQL 模式下)
    • grouping()grouping_id() 函数

    注意: GROUPING SETS 仅在 SQL 模式下可用。 Dataset API 不支持。

    分组集

    val sales = Seq(
      ("Warsaw", 2016, 100),
      ("Warsaw", 2017, 200),
      ("Boston", 2015, 50),
      ("Boston", 2016, 150),
      ("Toronto", 2017, 50)
    ).toDF("city", "year", "amount")
    sales.createOrReplaceTempView("sales")
    
    // equivalent to rollup("city", "year")
    val q = sql("""
      SELECT city, year, sum(amount) as amount
      FROM sales
      GROUP BY city, year
      GROUPING SETS ((city, year), (city), ())
      ORDER BY city DESC NULLS LAST, year ASC NULLS LAST
      """)
    
    scala> q.show
    +-------+----+------+
    |   city|year|amount|
    +-------+----+------+
    | Warsaw|2016|   100|
    | Warsaw|2017|   200|
    | Warsaw|null|   300|
    |Toronto|2017|    50|
    |Toronto|null|    50|
    | Boston|2015|    50|
    | Boston|2016|   150|
    | Boston|null|   200|
    |   null|null|   550|  <-- grand total across all cities and years
    +-------+----+------+
    
    // equivalent to cube("city", "year")
    // note the additional (year) grouping set
    val q = sql("""
      SELECT city, year, sum(amount) as amount
      FROM sales
      GROUP BY city, year
      GROUPING SETS ((city, year), (city), (year), ())
      ORDER BY city DESC NULLS LAST, year ASC NULLS LAST
      """)
    
    scala> q.show
    +-------+----+------+
    |   city|year|amount|
    +-------+----+------+
    | Warsaw|2016|   100|
    | Warsaw|2017|   200|
    | Warsaw|null|   300|
    |Toronto|2017|    50|
    |Toronto|null|    50|
    | Boston|2015|    50|
    | Boston|2016|   150|
    | Boston|null|   200|
    |   null|2015|    50|  <-- total across all cities in 2015
    |   null|2016|   250|  <-- total across all cities in 2016
    |   null|2017|   250|  <-- total across all cities in 2017
    |   null|null|   550|
    +-------+----+------+
    

    如果结果表的列中的值为null,则不一定意味着该列已在该行上聚合。如果该列在原始表中有nulls,则聚合表中的null 值可能仅代表原始表中的null 值。使用grouping 函数检查列是否聚合在特定行上。

    【讨论】:

    • 如何查询报告,例如我想在 2015 年跨城市获取总数。我是否需要将所有其他列设为空。例如,从表中选择金额,其中 year=2015 且城市为空,并且每隔一列为空
    • @PushpendraJaiswal 这正是我的建议。
    • 如果结果表的列中的值为空,则不一定意味着该列是在该行上聚合的。如果该列在原始表中有空值,则聚合表中的空值可能仅表示原始表中的空值。您可以使用grouping 函数检查该列是否在特定行上聚合。
    【解决方案2】:

    【讨论】:

    • 但是dataframe函数api怎么样。我找不到它。
    • 没有。它仅在 SQL 中可用。
    猜你喜欢
    • 1970-01-01
    • 2013-09-24
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    • 2023-02-24
    • 2014-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多