SparkSQL 中group by、grouping sets、rollup和cube方法详解

  • Post author:
  • Post category:其他




group by:

主要用来对查询的结果进行分组,相同组合的分组条件在结果集中只显示一行记录。可

group by:

主要用来对查询的结果进行分组,相同组合的分组条件在结果集中只显示一行记录。可以添加聚合函数。



grouping sets:

对分组集中指定的组表达式的每个子集执行group by,group by A,B grouping sets(A,B)就等价于 group by A union group by B,其中A和B也可以是一个集合,比如group by A,B,C grouping sets((A,B),(A,C)),最后在对每个分组进行union



rollup:

在指定表达式的每个层次级别创建分组集。group by A,B,C with rollup首先会对(A、B、C)进行group by,然后对(A、B)进行group by,然后是(A)进行group by,最后对全表进行group by操作,最后在对每个分组进行union



cube:

为指定表达式集的每个可能组合创建分组集。首先会对(A、B、C)进行group by,然后依次是(A、B),(A、C),(A),(B、C),(B),( C),最后对全表进行group by操作,最后在对每个分组进行union

import org.apache.spark.sql.SparkSession

object cubeTest {
    def main(args: Array[String]): Unit = {
        val spark = SparkSession.builder().appName("test").master("local")
            .getOrCreate()
        val list = Seq(
            NumberInfo("⼴东","深圳","今⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","东莞","今⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","珠海","今⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","深圳","昨⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","东莞","昨⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","珠海","昨⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","深圳","今⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","东莞","今⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","珠海","今⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","深圳","昨⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","东莞","昨⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","珠海","昨⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","深圳","前⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","东莞","前⽇疫情治愈⼈数",1),
            NumberInfo("⼴东","珠海","前⽇疫情治愈⼈数",1),
            NumberInfo("辽宁","锦州","今⽇疫情治愈⼈数",1),
            NumberInfo("辽宁","沈阳","今⽇疫情治愈⼈数",1),
            NumberInfo("辽宁","⼤连","今⽇疫情治愈⼈数",1),
            NumberInfo("辽宁","锦州","昨⽇疫情治愈⼈数",1),
            NumberInfo("辽宁","沈阳","昨⽇疫情治愈⼈数",1),
            NumberInfo("辽宁","⼤连","昨⽇疫情治愈⼈数",1),
            NumberInfo("辽宁","⼤连","今⽇疫情治愈⼈数",1),
            NumberInfo("辽宁","锦州","昨⽇疫情治愈⼈数",1),
            NumberInfo("辽宁","沈阳","昨⽇疫情治愈⼈数",1),
            NumberInfo("辽宁","⼤连","昨⽇疫情治愈⼈数",1)
        )
        import spark.implicits._
        val df = list.toDF()
        df.createTempView("log")
        // 按照省市情况进⾏分组聚合
        spark.sql("select pro,city,product,sum(number) from log group by pro,city,product").show()
//         grouping sets 是对每⼀个单独的维度求值
//         如果我们使⽤这个函数,那么他会对每⼀个分组后的维度进⾏单独分组求和
//         相当于⽤group by(每个字段) union group by (每个字段)....
        /**
         * +---+----+--------+-----------+
           |pro|city| product|sum(number)|
           +---+----+--------+-----------+
           | 辽宁|  沈阳|昨⽇疫情治愈⼈数|          2|
           | ⼴东|  珠海|前⽇疫情治愈⼈数|          1|
           | ⼴东|  东莞|前⽇疫情治愈⼈数|          1|
           | ⼴东|  东莞|今⽇疫情治愈⼈数|          2|
           | 辽宁|  沈阳|今⽇疫情治愈⼈数|          1|
           | ⼴东|  深圳|今⽇疫情治愈⼈数|          2|
           | ⼴东|  珠海|今⽇疫情治愈⼈数|          2|
           | 辽宁|  锦州|今⽇疫情治愈⼈数|          1|
           | 辽宁|  ⼤连|昨⽇疫情治愈⼈数|          2|
           | ⼴东|  深圳|昨⽇疫情治愈⼈数|          2|
           | 辽宁|  ⼤连|今⽇疫情治愈⼈数|          2|
           | 辽宁|  锦州|昨⽇疫情治愈⼈数|          2|
           | ⼴东|  东莞|昨⽇疫情治愈⼈数|          2|
           | ⼴东|  珠海|昨⽇疫情治愈⼈数|          2|
           | ⼴东|  深圳|前⽇疫情治愈⼈数|          1|
           +---+----+--------+-----------+
         */
        spark.sql("select pro,city,product,sum(number) from log group by pro,city,product grouping sets(pro,city,product)").show()
//
        /**
         * +----+----+--------+-----------+
        | pro|city| product|sum(number)|
        +----+----+--------+-----------+
        |null|null|昨⽇疫情治愈⼈数|         12|
        |null|  锦州|    null|          3|
        |null|null|前⽇疫情治愈⼈数|          3|
        |null|  ⼤连|    null|          4|
        |null|  沈阳|    null|          3|
        |null|  深圳|    null|          5|
        |  ⼴东|null|    null|         15|
        |null|null|今⽇疫情治愈⼈数|         10|
        |null|  珠海|    null|          5|
        |  辽宁|null|    null|         10|
        |null|  东莞|    null|          5|
        +----+----+--------+-----------+
         */
        //rollup 上卷
        //假如我们还是要求进⾏分组聚合求值,但是这个求值有变化,要求group by A B C 求ABC,AB,A,全表
        //扫描所有数据
        spark.sql("select pro,city,product,sum(number) from log group by pro,city,product with rollup").show(100)

        /**
         * +----+----+--------+-----------+
           | pro|city| product|sum(number)|
           +----+----+--------+-----------+
           |  ⼴东|  东莞|昨⽇疫情治愈⼈数|          2|
           |  辽宁|  锦州|昨⽇疫情治愈⼈数|          2|
           |  ⼴东|  深圳|前⽇疫情治愈⼈数|          1|
           |  辽宁|  锦州|    null|          3|
           |  辽宁|  沈阳|昨⽇疫情治愈⼈数|          2|
           |  辽宁|  沈阳|今⽇疫情治愈⼈数|          1|
           |  ⼴东|  深圳|今⽇疫情治愈⼈数|          2|
           |  辽宁|  ⼤连|今⽇疫情治愈⼈数|          2|
           |  ⼴东|  东莞|今⽇疫情治愈⼈数|          2|
           |  ⼴东|  珠海|前⽇疫情治愈⼈数|          1|
           |  辽宁|  锦州|今⽇疫情治愈⼈数|          1|
           |  ⼴东|  深圳|昨⽇疫情治愈⼈数|          2|
           |  ⼴东|null|    null|         15|
           |  辽宁|  沈阳|    null|          3|
           |null|null|    null|         25|
           |  ⼴东|  珠海|今⽇疫情治愈⼈数|          2|
           |  辽宁|  ⼤连|昨⽇疫情治愈⼈数|          2|
           |  ⼴东|  深圳|    null|          5|
           |  ⼴东|  东莞|    null|          5|
           |  ⼴东|  东莞|前⽇疫情治愈⼈数|          1|
           |  辽宁|null|    null|         10|
           |  ⼴东|  珠海|    null|          5|
           |  辽宁|  ⼤连|    null|          4|
           |  ⼴东|  珠海|昨⽇疫情治愈⼈数|          2|
           +----+----+--------+-----------+
         */
         // cube ⽴⽅体
        // 如果需求发⽣改变,要求你将分组后的维度,所有维度的结果都考虑到,例如group by A B C
        //,AB,AC,BC,A,B,C,全表扫描
        spark.sql("select pro,city,product,sum(number) from log group by pro,city,product with cube").show(200)
        /**
         * +----+----+--------+-----------+
           | pro|city| product|sum(number)|
           +----+----+--------+-----------+
           |  ⼴东|  东莞|昨⽇疫情治愈⼈数|          2|
           |  辽宁|  锦州|昨⽇疫情治愈⼈数|          2|
           |null|  锦州|今⽇疫情治愈⼈数|          1|
           |  ⼴东|null|昨⽇疫情治愈⼈数|          6|
           |null|  珠海|前⽇疫情治愈⼈数|          1|
           |null|null|昨⽇疫情治愈⼈数|         12|
           |null|  沈阳|今⽇疫情治愈⼈数|          1|
           |null|  锦州|    null|          3|
           |null|null|前⽇疫情治愈⼈数|          3|
           |null|  珠海|昨⽇疫情治愈⼈数|          2|
           |  辽宁|null|今⽇疫情治愈⼈数|          4|
           |  ⼴东|  深圳|前⽇疫情治愈⼈数|          1|
           |  辽宁|  锦州|    null|          3|
           |  辽宁|  沈阳|昨⽇疫情治愈⼈数|          2|
           |null|  ⼤连|    null|          4|
           |null|  沈阳|    null|          3|
           |  辽宁|  沈阳|今⽇疫情治愈⼈数|          1|
           |  ⼴东|  深圳|今⽇疫情治愈⼈数|          2|
           |  辽宁|  ⼤连|今⽇疫情治愈⼈数|          2|
           |  ⼴东|  东莞|今⽇疫情治愈⼈数|          2|
           |  ⼴东|  珠海|前⽇疫情治愈⼈数|          1|
           |null|  沈阳|昨⽇疫情治愈⼈数|          2|
           |  辽宁|  锦州|今⽇疫情治愈⼈数|          1|
           |null|  深圳|    null|          5|
           |null|  锦州|昨⽇疫情治愈⼈数|          2|
           |  ⼴东|  深圳|昨⽇疫情治愈⼈数|          2|
           |  ⼴东|null|前⽇疫情治愈⼈数|          3|
           |null|  ⼤连|昨⽇疫情治愈⼈数|          2|
           |null|  东莞|今⽇疫情治愈⼈数|          2|
           |  ⼴东|null|    null|         15|
           |  辽宁|  沈阳|    null|          3|
           |null|  东莞|前⽇疫情治愈⼈数|          1|
           |null|null|今⽇疫情治愈⼈数|         10|
           |null|null|    null|         25|
           |  ⼴东|  珠海|今⽇疫情治愈⼈数|          2|
           |null|  珠海|    null|          5|
           |  辽宁|  ⼤连|昨⽇疫情治愈⼈数|          2|
           |  ⼴东|null|今⽇疫情治愈⼈数|          6|
           |  ⼴东|  深圳|    null|          5|
           |  ⼴东|  东莞|    null|          5|
           |  ⼴东|  东莞|前⽇疫情治愈⼈数|          1|
           |  辽宁|null|    null|         10|
           |null|  ⼤连|今⽇疫情治愈⼈数|          2|
           |  ⼴东|  珠海|    null|          5|
           |  辽宁|  ⼤连|    null|          4|
           |null|  东莞|    null|          5|
           |null|  深圳|前⽇疫情治愈⼈数|          1|
           |  ⼴东|  珠海|昨⽇疫情治愈⼈数|          2|
           |null|  深圳|今⽇疫情治愈⼈数|          2|
           |null|  深圳|昨⽇疫情治愈⼈数|          2|
           |null|  东莞|昨⽇疫情治愈⼈数|          2|
           |  辽宁|null|昨⽇疫情治愈⼈数|          6|
           |null|  珠海|今⽇疫情治愈⼈数|          2|
           +----+----+--------+-----------+
         */
    }
}
case class NumberInfo(pro:String,city:String,product:String,number:Int)



版权声明:本文为LFQ244117370原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。