热门商品求top3

Spark 1.4.x版本以后,为Spark SQL和DataFrame引入了开窗函数,比如最经典,最常用的,row_number(),可以让我们实现分组取topn的逻辑。


案例:统计每个种类的销售额排名前3的产品

java版本


 
 
  1. package cn.spark.study.sql;
  2. import org.apache.spark.SparkConf;
  3. import org.apache.spark.api.java.JavaSparkContext;
  4. import org.apache.spark.sql.DataFrame;
  5. import org.apache.spark.sql.hive.HiveContext;
  6. /**
  7. * 84讲,row_number()开窗函数实战
  8. * @author leizq120310
  9. *
  10. */
  11. public class RowNumberWindowFunction {
  12. public static void main(String[] args) {
  13. // 创建SparkConf,集群运行
  14. SparkConf conf = new SparkConf()
  15. .setAppName( “RowNumberWindowFunction”);
  16. // 创建JavaSparkContext
  17. JavaSparkContext sc = new JavaSparkContext(conf);
  18. HiveContext hiveContext = new HiveContext( sc.sc());
  19. // 创建销售额表,sales表
  20. hiveContext.sql( “DROP TABLE IF EXISTS sales”);
  21. hiveContext.sql( “CREATE TABLE IF NOT EXISTS sales (”
  22. + “product STRING,”
  23. + "category STRING, "
  24. + “revenue BIGINT)”);
  25. hiveContext.sql( “LOAD DATA "
  26. + “LOCAL INPATH ‘/usr/local/spark-study/resources/sales.txt’ "
  27. + “INTO TABLE sales”);
  28. // 开始编写我们的统计逻辑,使用row_number()开窗函数
  29. // 先说明一下,row_number()开窗函数的作用
  30. // 其实,就是给每个分组的数所在,按照其排序顺序,打上一个分组内的行号
  31. // 比如说,有一个分组date=20151001, 里面有3条数据,1122,1121,1124,
  32. // 那么对这个分组的每一行使用row_number()开窗函数以后,三行,依次会获得一个组内的行号
  33. // 行号从1开始递增,比如1122 1, 1121 2, 1124, 3
  34. DataFrame top3SaleDF = hiveContext.sql( ””
  35. + "SELECT product, category,revenue "
  36. + “FROM (”
  37. + "SELECT "
  38. + "product, "
  39. + "category, "
  40. + "revenue, "
  41. // row_number()开窗函数的语法说明
  42. // 首先可以,在SELECT查询时,使用row_number()函数
  43. // 其次,row_number()函数后面先跟上OVER关键字
  44. // 然后括号中,是PARTITION BY,也就是说根据哪个字段进行分组
  45. // 其次是可以用ORDER BY 进行组内排序
  46. // 然后row_number()就可以给每个组内的行,一个组内行号
  47. + "row_number() OVER (PARTITION BY category ORDER BY revenue DESC) rank "
  48. + "FROM sales "
  49. + ") tmp_sales "
  50. + “WHERE rank<=3”);
  51. // 将每组排名前3的数据,保存到一个表中
  52. hiveContext.sql( “DROP TABLE IF EXISTS top3_sales”);
  53. top3SaleDF.saveAsTable( “top3_sales”);
  54. // 关闭JavaSparkContext
  55. sc.close();
  56. }
  57. }
scala版本:
package cn.spark.study.sql

import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.sql.DataFrame;
import org.apache.spark.sql.hive.HiveContext;

/**

  • 84讲,row_number()开窗函数实战
  • @author leizq120310

*/

object RowNumberWindowFunction {
def main(args:Array[String])
{
// 创建SparkConf,集群运行
val conf = new SparkConf()
.setAppName(“RowNumberWindowFunction”);

	<span class="hljs-comment">// 创建JavaSparkContext</span>
	<span class="hljs-keyword">val</span> sc = new JavaSparkContext(conf);
	<span class="hljs-keyword">val</span> hiveContext = new HiveContext(sc);
	
	<span class="hljs-comment">// 创建销售额表,sales表</span>
	hiveContext.sql(<span class="hljs-string">"DROP TABLE IF EXISTS sales"</span>);
	hiveContext.sql(<span class="hljs-string">"CREATE TABLE IF NOT EXISTS sales ("</span>
			+ <span class="hljs-string">"product STRING,"</span>
			+ <span class="hljs-string">"category STRING, "</span>
			+ <span class="hljs-string">"revenue BIGINT)"</span>);
	hiveContext.sql(<span class="hljs-string">"LOAD DATA "</span>
			+ <span class="hljs-string">"LOCAL INPATH '/usr/local/spark-study/resources/sales.txt' "</span>
			+ <span class="hljs-string">"INTO TABLE sales"</span>);
	
	<span class="hljs-comment">// 开始编写我们的统计逻辑,使用row_number()开窗函数</span>
	<span class="hljs-comment">// 先说明一下,row_number()开窗函数的作用</span>
	<span class="hljs-comment">// 其实,就是给每个分组的数所在,按照其排序顺序,打上一个分组内的行号</span>
	<span class="hljs-comment">// 比如说,有一个分组date=20151001, 里面有3条数据,1122,1121,1124,</span>
	<span class="hljs-comment">// 那么对这个分组的每一行使用row_number()开窗函数以后,三行,依次会获得一个组内的行号</span>
	<span class="hljs-comment">// 行号从1开始递增,比如1122 1, 1121 2, 1124, 3</span>
	<span class="hljs-keyword">val</span> top3SaleDF = hiveContext.sql(<span class="hljs-string">""</span>
			+ <span class="hljs-string">"SELECT product, category,revenue "</span>
			+ <span class="hljs-string">"FROM ("</span>
				+ <span class="hljs-string">"SELECT "</span>
					+ <span class="hljs-string">"product, "</span>
					+ <span class="hljs-string">"category, "</span>
					+ <span class="hljs-string">"revenue, "</span>
					<span class="hljs-comment">// row_number()开窗函数的语法说明</span>
					<span class="hljs-comment">// 首先可以,在SELECT查询时,使用row_number()函数</span>
					<span class="hljs-comment">// 其次,row_number()函数后面先跟上OVER关键字</span>
					<span class="hljs-comment">// 然后括号中,是PARTITION BY,也就是说根据哪个字段进行分组</span>
					<span class="hljs-comment">// 其次是可以用ORDER BY 进行组内排序</span>
					<span class="hljs-comment">// 然后row_number()就可以给每个组内的行,一个组内行号</span>
					+ <span class="hljs-string">"row_number() OVER (PARTITION BY category ORDER BY revenue DESC) rank "</span>
					+ <span class="hljs-string">"FROM sales "</span>
			+ <span class="hljs-string">") tmp_sales "</span>
			+ <span class="hljs-string">"WHERE rank&lt;=3"</span>);
	<span class="hljs-comment">// 将每组排名前3的数据,保存到一个表中</span>
	hiveContext.sql(<span class="hljs-string">"DROP TABLE IF EXISTS top3_sales"</span>);
	top3SaleDF.saveAsTable(<span class="hljs-string">"top3_sales"</span>);
	
	<span class="hljs-comment">// 关闭JavaSparkContext</span>
	sc.close();

}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值