Spark SQL 开窗函数row_number的使用
窗口函数 row_number即为分组取topN
参考文本: 型号 类别 销售量/月
小米,手机,250
华为,手机,450
苹果,手机,1000
三星,手机,2500
小米Pro,笔记本,1500
苹果Pro,笔记本,2000
三星Pro,笔记本,4100
华为ProX,笔记本,200
华硕,笔记本,10000
苹果,平板电脑,100
三星,平板电脑,200
华为,平板电脑,300
中兴,平板电脑,400
需求分析 : 根据文本中的类别进行分组,取月销售额的前三名:
代码:
package com.bynear.spark_sql;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.Row;
import org.apache.spark.sql.SaveMode;
import org.apache.spark.sql.hive.HiveContext;
import java.util.List;
public class RowNumberWindowFunction {
public static void main(String[] args) {
SparkConf conf = new SparkConf();
JavaSparkContext sc = new JavaSparkContext(conf);
HiveContext hiveContext = new HiveContext(sc.sc());
// 创建销售额表 sales
hiveContext.sql("drop table if exists sales");
// hiveContext.sql("create table if not exists sales (product string, category string, revenue BIGINT)
// row format delimited\\n\" +\n" +
// " \" fields terminated by ','");
hiveContext.sql(
"create table if not exists sales (product string, category string, revenue bigint) row format delimited fields terminated by ',' "
);
hiveContext.sql("load data inpath" +
" 'hdfs://Spark01:9000/zjs/sales.txt' into table sales ");
//
DataFrame top3SalesDF = hiveContext.sql("select product,category,revenue from (select product, category, revenue, row_number() over (partition by category order by revenue DESC ) rank from sales ) tmp_sales where rank <=3");
hiveContext.sql("drop table if exists top_sales");
hiveContext.sql("create table top_sales (product string, category string, revenue bigint) ");
top3SalesDF.write().mode(SaveMode.Append).insertInto("top_sales");
List rows = top3SalesDF.javaRDD().collect();
for (Row row : rows) {
System.out.println(row);
}
top3SalesDF.write().format("json").save("hdfs://Spark01:9000/zjs/JSON");
sc.close();
}
}
注意点:文本中尽量使用英文逗号进行分割! 如果在hive库中出现 按照逗号分割之后,每行的结尾出现 NULL, 即为编码的问题!需要将文本转化为UTF-8格式,问题解决。
重点在于SQL语句中的 row_number,查看括弧是否匹配齐全!
在我的集群出现的问题!使用saveASTable方法的时候,集群直接报错!没有办法,只能使用insertInto方法了,但是必须要在代码中,手动去创建一个表,来存储最
终的结果!使用insertInto方法把结果insert到创建好的表中!
问题:为什么在我的集群中,将用例文件上传到 集群上之后,每运行一下Spark命令之后,集群上的用例文本就会被删除掉!该如何解决!
希望大佬们给出解决的方法!
开窗函数格式:
* 【 row_number() over (partition by XXX order by XXX) as rank】//起个别名
* 注意:rank 从1开始
运行结果:
[中兴,平板电脑,400]
[华为,平板电脑,300]
[三星,平板电脑,200]
[三星,手机,2500]
[苹果,手机,1000]
[华为,手机,450]
[华硕,笔记本,10000]
[三星Pro,笔记本,4100]
[苹果Pro,笔记本,2000]