Spark开窗函数之ROW_NUMBER()

 

一、row_number函数的用法:

 

(1)Spark 1.5.x版本以后,在Spark SQL和DataFrame中引入了开窗函数,其中比较常用的开窗函数就是row_number 
     该函数的作用是根据表中字段进行分组,然后根据表中的字段排序;其实就是根据其排序顺序,给组中的每条记录添
     加一个序号;且每组的序号都是从1开始,可利用它的这个特性进行分组取top-n。
(2)如果SQL语句里面使用到了开窗函数,那么这个SQL语句必须使用HiveContext来执行,HiveContext默认情况下在
    本地无法创建。
(3)row_number的格式:
    ROW_NUMBER() OVER (PARTITION BY 'xxx' ORDER BY 'xxx' DESC) rank

二、利用row_number实现分组取top3

* 实验数据
 * user表中:
 * id       age     deptId
 * 001      21      d1
 * 002      23      d2
 * 003      31      d1
 * 004      27      d2
 * 005      28      d1
 * 006      25      d2
 * 007      41      d1
 * 008      33      d2
 * 009      36      d1
 * 010      42      d2
 * 011      37      d1
 * 012      24      d2
 *
 * 如果利用row_number()实现按deptId分组根据age降序取top-3,最后结果为:
 * id       age     deptId
 * 007      41      d1
 * 011      37      d1
 * 009      36      d1
 * 010      42      d2
 * 008      33      d2
 * 006      25      d2
 */
public class OpenwidowFunctionDemo {

    public static void main(String[] args){
        //创建配置
        SparkConf conf = new SparkConf()
                .setAppName("openwindowFunctionDemo");

        //创建提交spark应用的集群入口类对象
        JavaSparkContext sc = new JavaSparkContext(conf);
        //创建SQLContext对象
        SQLContext sqlContext = new HiveContext(sc.sc());

        //加载数据
        sqlContext.sql("use spark");
        sqlContext.sql("drop table if exists user");
        sqlContext.sql("create table if not exists user (userId string,age int,deptId string) "
                + "row format delimited fields terminated by '\t'");
        sqlContext.sql("load data local inpath '/home/user.txt' into table user");

        String sql = "SELECT "
                +"userId,"
                +"age,"
                +"deptId "
                +"FROM ("
                    +"SELECT "
                    +"userId,"
                    +"age,"
                    +"deptId "
                    +"ROW_NUMBER() OVER (PARTITION BY deptId ORDER BY age DESC) rank"
                    +"FROM user"
                    +") tmp_user"
                +"WHERE rank <= 3";
        //执行查询
        DataFrame df = sqlContext.sql(sql);

        df.show();

        //将结果写入Hive表中
        df.write().mode(SaveMode.Overwrite).saveAsTable("user_top3_res");

        sc.stop();

    }
}

 

你可能感兴趣的:(spark)