SparkSQL项目实战练习——各区域热门商品TOP3

目录

一、环境要求

二、数据准备

三、需求说明

四、代码实现

1.建立3张表:

 2.需求实现


一、环境要求

IDEA中SPARK可以连接虚拟机外置HIVE 可参考(IDEA中Spark连接外置hive详细步骤

Spark3.0.0;Hadoop3.2.1; HIVE3.1.2

二、数据准备

1 张用户行为表,1 张城市表,1 张产品表

  • 用户行为表user_visit_action:

主要包含用户的 4 种行为:搜索,点击,下单,支付。数据规则如下:

➢ 数据文件中每行数据采用下划线分隔数据

➢ 每一行数据表示用户的一次行为,这个行为只能是 4 种行为的一种

➢ 如果点击的品类 ID 和产品 ID 为-1,表示数据不是点击数据

本次需求关键的字段:

click_product_id,city_id
  • 城市表city_info:

包含城市及地区

  • 产品表product_info:

包含商品名称和渠道(自营或第三方)

三、需求说明

需求:各区域热门商品 Top3

这里的热门商品是从点击量的维度来看的,计算各个区域前三大热门商品,并备注上每个商品在主要城市中的分布比例,超过两个城市用其他显示。

地区商品名称点击次数城市备注
华北商品A100000北京21.2%,天津 13.2%,其他 65.6%
华北商品 P80200北京 63.0%,太原 10%,其他 27.0%
华北商品 M40000北京 63.0%,太原 10%,其他 27.0%
东北商品 J92000大连 28%,辽宁 17.0%,其他 55.0%

四、代码实现

1.建立3张表:

 def main(args: Array[String]): Unit = {
        System.setProperty("HADOOP_USER_NAME", "root")

        val sparkConf = new SparkConf().setMaster("local[*]").setAppName("sparkSQL")
        val spark = 
            SparkSession
            .builder()
            .enableHiveSupport()
            .config(sparkConf)
            .config("dfs.client.use.datanode.hostname", "true")
            .config("dfs.replication", "2")
            .getOrCreate()

        spark.sql("use hive")

        // 准备数据
        spark.sql(
            """
              |CREATE TABLE `user_visit_action`(
              |  `date` string,
              |  `user_id` bigint,
              |  `session_id` string,
              |  `page_id` bigint,
              |  `action_time` string,
              |  `search_keyword` string,
              |  `click_category_id` bigint,
              |  `click_product_id` bigint,
              |  `order_category_ids` string,
              |  `order_product_ids` string,
              |  `pay_category_ids` string,
              |  `pay_product_ids` string,
              |  `city_id` bigint)
              |row format delimited fields terminated by '\t'
            """.stripMargin)

        spark.sql(
            """
              |load data local inpath './datas/user_visit_action.txt' into table hive.user_visit_action
            """.stripMargin)

        spark.sql(
            """
              |CREATE TABLE `product_info`(
              |  `product_id` bigint,
              |  `product_name` string,
              |  `extend_info` string)
              |row format delimited fields terminated by '\t'
            """.stripMargin)

        spark.sql(
            """
              |load data local inpath './datas/product_info.txt' into table hive.product_info
            """.stripMargin)

        spark.sql(
            """
              |CREATE TABLE `city_info`(
              |  `city_id` bigint,
              |  `city_name` string,
              |  `area` string)
              |row format delimited fields terminated by '\t'
            """.stripMargin)

        spark.sql(
            """
              |load data local inpath './datas/city_info.txt' into table hive.city_info
            """.stripMargin)

        spark.sql("""select * from city_info""").show


        spark.close()
    }

在运行过程中出现报错:

ERROR Hive: Failed to move: org.apache.hadoop.ipc.RemoteException(java.io.IOException): File /user/hive/warehouse/hdu.db/user_visit_action/user_visit_action.txt could only be written to 0 of the 1 minReplication nodes. There are 1 datanode(s) running and 1 node(s) are excluded in this operation.

报错说我datanode有异常,首先我检查了datanode是正常启动的,后来解决方法如下:

NameNode节点存放的是文件目录,也就是文件夹、文件名称,本地可以通过公网访NameNode,所以可以进行文件夹的创建,当上传文件需要写入数据到DataNode时,NameNode 和DataNode 是通过局域网进行通信,NameNode返回地址为 DataNode 的私有 IP,本地无法访问返回的IP地址无法返回公网IP,所以通过设置让其返回主机名,通过主机名与公网地址的映射便可以访问到DataNode节点,问题将解决。
由于代码的设置的优先级为最高,所以直接进行代码的设置:在sparksession中添加配置信息即可:

config("dfs.client.use.datanode.hostname", "true")
config("dfs.replication", "2")

 2.需求实现

文字部分比较麻烦,可以用udf也可以使用sql。

    spark.sql(
      """
        |select
        |*
        |from
        |
        |(
        | select
        |     t2.*,
        |     row_number() over(partition by t2.area order by t2.cli_cnt desc) rank
        |     from
        |     (
        |     select
        |       t1.area,
        |       t1.product_name,
        |       count(*) as cli_cnt
        |       from
        |       (select
        |         c.area,
        |         c.city_name,
        |         p.product_name,
        |         u.click_product_id
        |         from
        |         city_info c
        |         left join user_visit_action u on c.city_id =  u.city_id
        |         left join product_info p on u.click_product_id = p.product_id) t1
        |         where click_product_id >=0
        |         group by t1.area, t1.product_name
        |         ) t2
        |      )t3 where rank <= 3
        |
        |
        |
        |""".stripMargin
    ).createOrReplaceTempView("d1")

    //    城市备注部分,将商品和城市连接,需要取得每个商品TOP2城市的点击次数,文字部分用concat,多行聚合可以使用group_concat(sparksql不支持)/concat_ws
    spark.sql(
      """
        |select t6.product_name,t6.area, concat_ws(',', collect_set(info1)) as info
        |from
        |(select
        |*,
        |concat(city,round((case when rank1 = 3 then total-sum_+cnt else cnt end)*100/total,1),'%') info1
        |from
        |(select *,
        |(case when rank1 =3 then '其他' else city_name end) city,
        |sum(cnt) over (partition by product_name,area order by rank1 asc) sum_
        | from
        |(select
        |t3.*,
        |row_number() over(partition by t3.product_name order by cnt desc) rank1
        |
        | from
        | (select
        |   t2.*,
        |   sum(cnt) over(partition by area,product_name) total
        |   from
        |   (select
        |      t1.city_name,
        |      t1.product_name,
        |      t1.area,
        |      count(*) as cnt
        |      from
        |       (select
        |         c.area,
        |         c.city_name,
        |         p.product_name,
        |         u.click_product_id
        |         from
        |         city_info c
        |         left join user_visit_action u on c.city_id =  u.city_id
        |         left join product_info p on u.click_product_id = p.product_id) t1
        |       where click_product_id >=0
        |       group by product_name,area,city_name) t2)t3
        |join d1 on d1.product_name = t3.product_name and d1.area = t3.area)t4
        |  where  t4.rank1 <=3)t5  order by area,product_name,rank1 asc
        |)t6
        |group by area,product_name
        |order by area,product_name asc
        |""".stripMargin
    ).createOrReplaceTempView("d2")

    spark.sql(
      """
        |select
        |   d1.area,
        |   d1.product_name,
        |   d1.cli_cnt,
        |   d2.info
        |from
        |   d1
        |   left join d2
        |   on d1.product_name = d2.product_name and d1.area = d2.area
        |   order by area,rank asc
        |""".stripMargin
    ).show

结果图: 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: 好的,下面是SparkSQL代码笔记03——连接Hive的中文回复: 在SparkSQL中,我们可以通过以下步骤连接Hive: 1. 首先,需要在SparkSession中启用Hive支持,可以使用以下代码: ``` from pyspark.sql import SparkSession spark = SparkSession.builder \ .appName("SparkSQL Hive Example") \ .config("spark.sql.warehouse.dir", "/user/hive/warehouse") \ .enableHiveSupport() \ .getOrCreate() ``` 其中,`enableHiveSupport()`方法启用了Hive支持,`config("spark.sql.warehouse.dir", "/user/hive/warehouse")`指定了Hive元数据存储的目录。 2. 接下来,我们可以使用`spark.sql()`方法执行Hive SQL语句,例如: ``` spark.sql("show databases").show() ``` 这将显示所有的Hive数据库。 3. 如果需要在SparkSQL中访问Hive表,可以使用以下代码: ``` df = spark.sql("select * from my_hive_table") ``` 其中,`my_hive_table`是Hive中的表名。 4. 如果需要在SparkSQL中创建Hive表,可以使用以下代码: ``` spark.sql("create table my_hive_table (id int, name string)") ``` 这将在Hive中创建一个名为`my_hive_table`的表,包含两个列:`id`和`name`。 以上就是连接Hive的基本步骤。需要注意的是,连接Hive需要在Spark集群中安装Hive,并且需要将Hive的JAR包添加到Spark的CLASSPATH中。 ### 回答2: SparkSQL是Apache Spark的一个组件,它提供了用于分布式数据处理的高级SQL查询引擎。SparkSQL支持连接多种数据源,其中之一就是Hive。 如何连接Hive? 在开始连接Hive之前,我们需要确保Hadoop和Hive的配置已经被正确的设置好了,以便Spark能够访问Hive元数据和数据。 首先,我们需要在Spark环境中添加Hive支持。运行下面的代码: `from pyspark.sql import SparkSession spark = SparkSession.builder \ .appName("hive_support") \ .enableHiveSupport() \ .getOrCreate()` 其中,`.enableHiveSupport()`将启用hive支持。 接下来,我们可以使用SparkSession连接Hive。运行下面的代码: `hive_df = spark.sql("SELECT * FROM default.student")` 其中,“default”是Hive的默认数据库,“student”是Hive数据库中的表名。 如果你要访问非默认的Hive数据库,可以使用下面的代码: `hive_df = spark.sql("SELECT * FROM dbname.student")` 其中,“dbname”是非默认的Hive数据库名。 我们还可以使用HiveContext来连接Hive。运行下面的代码: `from pyspark.sql import HiveContext hive_context = HiveContext(sc)` 其中,“sc”是SparkContext对象。 我们可以像这样从Hive中检索数据: `hive_df = hive_ctx.sql("SELECT * FROM default.student")` 现在你已经成功地连接Hive并从中检索了数据,你可以使用SparkSQL的强大功能对数据进行分析。而在连接Hive之外,在SparkSQL中还可以连接其他数据源,包括MySQL、PostgreSQL、Oracle等。 ### 回答3: Spark SQL是一个强大的分布式计算引擎,它可以支持处理多种数据源,并可通过Spark SQL shell、Spark应用程序或JDBC/ODBC接口等方式进行操作。其中,连接HiveSpark SQL最常用的数据源之一。下面,将介绍如何通过Spark SQL连接Hive。 1、在Spark配置中设置Hive Support 要连接Hive,首先需要在Spark配置中开启Hive Support。在启动Spark Shell时,可以添加如下参数: ``` ./bin/spark-shell --master local \ --conf spark.sql.warehouse.dir="/user/hive/warehouse" \ --conf spark.sql.catalogImplementation=hive \ --conf spark.sql.hive.metastore.version=0.13 \ --conf spark.sql.hive.metastore.jars=maven ``` 这里以本地模式为例,设置Spark SQL的元数据存储在本地文件系统中,设置Hive为catalog实现,以及为Hive Metastore设置版本和JAR文件路径。根据实际情况,还可以指定其他参数,如Hive Metastore地址、数据库名称、用户名和密码等。 2、创建SparkSession对象 在连接Hive之前,需要先创建SparkSession对象。可以通过调用SparkSession.builder()静态方法来构建SparkSession对象,如下所示: ``` val spark = SparkSession.builder() .appName("SparkSQLTest") .config("spark.sql.warehouse.dir", "/user/hive/warehouse") .enableHiveSupport() .getOrCreate() ``` 这里通过builder()方法指定应用程序名称、元数据存储路径以及启用Hive Support,最后调用getOrCreate()方法创建SparkSession对象。 3、通过Spark SQL操作Hive表 通过Spark SQL连接Hive后,就可以通过Spark SQL语句来操作Hive表了。例如,我们可以使用select语句查询Hive表中的数据: ``` val df = spark.sql("SELECT * FROM tablename") df.show() ``` 其中,select语句指定要查询的列和表名,然后通过show()方法来显示查询结果。 除了查询数据之外,Spark SQL还可以通过insertInto语句将数据插入到Hive表中: ``` val data = Seq(("Alice", 25), ("Bob", 30)) val rdd = spark.sparkContext.parallelize(data) val df = rdd.toDF("name", "age") df.write.mode(SaveMode.Append).insertInto("tablename") ``` 这里先创建一个包含数据的RDD对象,然后将其转换为DataFrame对象,并指定列名。接着,通过insertInto()方法将DataFrame对象中的数据插入到Hive表中。 总之,通过Spark SQL连接Hive可以方便地查询、插入、更新和删除Hive表中的数据,从而实现更加灵活和高效的数据处理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据求学家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值