一、创建DataFrame和Dataset

1.1 创建DataFrame

Spark 中所有功能的入口点是 SparkSession,可以使用 SparkSession.builder() 创建。创建后应用程序就可以从现有 RDD,Hive 表或 Spark 数据源创建 DataFrame。示例如下:

val spark = SparkSession.builder().appName("Spark-SQL").master("local[2]").getOrCreate()
val df = spark.read.json("/usr/file/json/emp.json")
df.show() // 建议在进行 spark SQL 编程前导入下面的隐式转换,因为 DataFrames 和 dataSets 中很多操作都依赖了隐式转换
import spark.implicits._

可以使用 spark-shell 进行测试,需要注意的是 spark-shell 启动后会自动创建一个名为 sparkSparkSession,在命令行中可以直接引用即可:

1.2 创建Dataset

Spark 支持由内部数据集和外部数据集来创建 DataSet,其创建方式分别如下:

1. 由外部数据集创建

// 1.需要导入隐式转换
import spark.implicits._ // 2.创建 case class,等价于 Java Bean
case class Emp(ename: String, comm: Double, deptno: Long, empno: Long,
hiredate: String, job: String, mgr: Long, sal: Double) // 3.由外部数据集创建 Datasets
val ds = spark.read.json("/usr/file/emp.json").as[Emp]
ds.show()

2. 由内部数据集创建

// 1.需要导入隐式转换
import spark.implicits._ // 2.创建 case class,等价于 Java Bean
case class Emp(ename: String, comm: Double, deptno: Long, empno: Long,
hiredate: String, job: String, mgr: Long, sal: Double) // 3.由内部数据集创建 Datasets
val caseClassDS = Seq(Emp("ALLEN", 300.0, 30, 7499, "1981-02-20 00:00:00", "SALESMAN", 7698, 1600.0),
Emp("JONES", 300.0, 30, 7499, "1981-02-20 00:00:00", "SALESMAN", 7698, 1600.0))
.toDS()
caseClassDS.show()

1.3 由RDD创建DataFrame

Spark 支持两种方式把 RDD 转换为 DataFrame,分别是使用反射推断和指定 Schema 转换:

1. 使用反射推断

// 1.导入隐式转换
import spark.implicits._ // 2.创建部门类
case class Dept(deptno: Long, dname: String, loc: String) // 3.创建 RDD 并转换为 dataSet
val rddToDS = spark.sparkContext
.textFile("/usr/file/dept.txt")
.map(_.split("\t"))
.map(line => Dept(line(0).trim.toLong, line(1), line(2)))
.toDS() // 如果调用 toDF() 则转换为 dataFrame

2. 以编程方式指定Schema

import org.apache.spark.sql.Row
import org.apache.spark.sql.types._ // 1.定义每个列的列类型
val fields = Array(StructField("deptno", LongType, nullable = true),
StructField("dname", StringType, nullable = true),
StructField("loc", StringType, nullable = true)) // 2.创建 schema
val schema = StructType(fields) // 3.创建 RDD
val deptRDD = spark.sparkContext.textFile("/usr/file/dept.txt")
val rowRDD = deptRDD.map(_.split("\t")).map(line => Row(line(0).toLong, line(1), line(2))) // 4.将 RDD 转换为 dataFrame
val deptDF = spark.createDataFrame(rowRDD, schema)
deptDF.show()

1.4 DataFrames与Datasets互相转换

Spark 提供了非常简单的转换方法用于 DataFrame 与 Dataset 间的互相转换,示例如下:

# DataFrames转Datasets
scala> df.as[Emp]
res1: org.apache.spark.sql.Dataset[Emp] = [COMM: double, DEPTNO: bigint ... 6 more fields] # Datasets转DataFrames
scala> ds.toDF()
res2: org.apache.spark.sql.DataFrame = [COMM: double, DEPTNO: bigint ... 6 more fields]

二、Columns列操作

2.1 引用列

Spark 支持多种方法来构造和引用列,最简单的是使用 col() column() 函数。

col("colName")
column("colName") // 对于 Scala 语言而言,还可以使用$"myColumn"和'myColumn 这两种语法糖进行引用。
df.select($"ename", $"job").show()
df.select('ename, 'job).show()

2.2 新增列

// 基于已有列值新增列
df.withColumn("upSal",$"sal"+1000)
// 基于固定值新增列
df.withColumn("intCol",lit(1000))

2.3 删除列

// 支持删除多个列
df.drop("comm","job").show()

2.4 重命名列

df.withColumnRenamed("comm", "common").show()

需要说明的是新增,删除,重命名列都会产生新的 DataFrame,原来的 DataFrame 不会被改变。

三、使用Structured API进行基本查询

// 1.查询员工姓名及工作
df.select($"ename", $"job").show() // 2.filter 查询工资大于 2000 的员工信息
df.filter($"sal" > 2000).show() // 3.orderBy 按照部门编号降序,工资升序进行查询
df.orderBy(desc("deptno"), asc("sal")).show() // 4.limit 查询工资最高的 3 名员工的信息
df.orderBy(desc("sal")).limit(3).show() // 5.distinct 查询所有部门编号
df.select("deptno").distinct().show() // 6.groupBy 分组统计部门人数
df.groupBy("deptno").count().show()

四、使用Spark SQL进行基本查询

4.1 Spark SQL基本使用

// 1.首先需要将 DataFrame 注册为临时视图
df.createOrReplaceTempView("emp") // 2.查询员工姓名及工作
spark.sql("SELECT ename,job FROM emp").show() // 3.查询工资大于 2000 的员工信息
spark.sql("SELECT * FROM emp where sal > 2000").show() // 4.orderBy 按照部门编号降序,工资升序进行查询
spark.sql("SELECT * FROM emp ORDER BY deptno DESC,sal ASC").show() // 5.limit 查询工资最高的 3 名员工的信息
spark.sql("SELECT * FROM emp ORDER BY sal DESC LIMIT 3").show() // 6.distinct 查询所有部门编号
spark.sql("SELECT DISTINCT(deptno) FROM emp").show() // 7.分组统计部门人数
spark.sql("SELECT deptno,count(ename) FROM emp group by deptno").show()

4.2 全局临时视图

上面使用 createOrReplaceTempView 创建的是会话临时视图,它的生命周期仅限于会话范围,会随会话的结束而结束。

你也可以使用 createGlobalTempView 创建全局临时视图,全局临时视图可以在所有会话之间共享,并直到整个 Spark 应用程序终止后才会消失。全局临时视图被定义在内置的 global_temp 数据库下,需要使用限定名称进行引用,如 SELECT * FROM global_temp.view1

// 注册为全局临时视图
df.createGlobalTempView("gemp") // 使用限定名称进行引用
spark.sql("SELECT ename,job FROM global_temp.gemp").show()

参考资料

Spark SQL, DataFrames and Datasets Guide > Getting Started

系列传送门

入门大数据---Spark_Structured API的基本使用的更多相关文章

  1. 入门大数据---Flink学习总括

    第一节 初识 Flink 在数据激增的时代,催生出了一批计算框架.最早期比较流行的有MapReduce,然后有Spark,直到现在越来越多的公司采用Flink处理.Flink相对前两个框架真正做到了高 ...

  2. 入门大数据---SparkSQL外部数据源

    一.简介 1.1 多数据源支持 Spark 支持以下六个核心数据源,同时 Spark 社区还提供了多达上百种数据源的读取方式,能够满足绝大部分使用场景. CSV JSON Parquet ORC JD ...

  3. 入门大数据---Hadoop是什么?

    简单概括:Hadoop是由Apache组织使用Java语言开发的一款应对大数据存储和计算的分布式开源框架. Hadoop的起源 2003-2004年,Google公布了部分GFS和MapReduce思 ...

  4. 入门大数据---Kylin是什么?

    一.Kylin是什么? Apache Kylin是一个开源的.分布式的分析型数据仓库,提供Hadoop/Spark 上的SQL查询接口及多维度分析(OLAP)能力以支持超大规模的数据,最初由eBay开 ...

  5. 入门大数据---Spark_Streaming整合Flume

    一.简介 Apache Flume 是一个分布式,高可用的数据收集系统,可以从不同的数据源收集数据,经过聚合后发送到分布式计算框架或者存储系统中.Spark Straming 提供了以下两种方式用于 ...

  6. 入门大数据---MapReduce-API操作

    一.环境 Hadoop部署环境: Centos3.10.0-327.el7.x86_64 Hadoop2.6.5 Java1.8.0_221 代码运行环境: Windows 10 Hadoop 2.6 ...

  7. 入门大数据---Flume整合Kafka

    一.背景 先说一下,为什么要使用 Flume + Kafka? 以实时流处理项目为例,由于采集的数据量可能存在峰值和峰谷,假设是一个电商项目,那么峰值通常出现在秒杀时,这时如果直接将 Flume 聚合 ...

  8. 入门大数据---安装ClouderaManager,CDH和Impala,Hue,oozie等服务

    1.要求和支持的版本 (PS:我使用的环境,都用加粗标识了.) 1.1 支持的操作系统版本 操作系统 版本 RHEL/CentOS/OL with RHCK kernel 7.6, 7.5, 7.4, ...

  9. 入门大数据---Spark整体复习

    一. Spark简介 1.1 前言 Apache Spark是一个基于内存的计算框架,它是Scala语言开发的,而且提供了一站式解决方案,提供了包括内存计算(Spark Core),流式计算(Spar ...

随机推荐

  1. Linux(六)文件系统

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 一.根目录内容 1.概述 Linux系统中只有一个文件系统,以“/”作为根目录,从根目录出发可以找到任何 ...

  2. SQL Server数据库附加失败错误:5123,拒绝访问

    发生错误的图片如下 我们需要更改数据库文件的权限(mdf和ldf两个文件) 右键数据库文件,点击属性 选择安全,点击高级,把每一个角色的访问权限都变成完全控制 如图所示 然后确定确定确定保存等等, l ...

  3. Java实现 蓝桥杯 算法提高 矩阵相乘

    算法提高 矩阵相乘 时间限制:1.0s 内存限制:256.0MB 问题描述 小明最近在为线性代数而头疼,线性代数确实很抽象(也很无聊),可惜他的老师正在讲这矩阵乘法这一段内容. 当然,小明上课打瞌睡也 ...

  4. Java实现选号码

    选号码 Description CF打算换个手机号码,但是他去营业厅选号码的时候却把移动的客服小姐烦得不行,因为他太挑三捡四啦. 对于一个手机号的后六位数字(前面五位他就无所谓了)CF有很严格的要求, ...

  5. Java实现 LeetCode 29 两数相除

    29. 两数相除 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商 ...

  6. Java实现 LeetCode 7整数反转

    7. 整数反转 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: -321 示例 3: 输入: ...

  7. 第五届蓝桥杯JavaC组省赛真题

    解题代码部分来自网友,如果有不对的地方,欢迎各位大佬评论 题目1.猜年龄 题目描述 小明带两个妹妹参加元宵灯会.别人问她们多大了,她们调皮地说:"我们俩的年龄之积是年龄之和的6倍" ...

  8. Android studio怎么导入Recycler VIew

    有可能你导入的RecyclerView只显示一行,是因为导错了包,当时可能没问题,当你用Adapter运行的时候会疯狂报错(别问我怎么知道的,我就是从那里出来的) 首先,打开build.gradle( ...

  9. java实现第五届蓝桥杯六角填数

    六角填数 题目描述 如图[1.png]所示六角形中,填入1~12的数字. 使得每条直线上的数字之和都相同. 图中,已经替你填好了3个数字,请你计算星号位置所代表的数字是多少? 请通过浏览器提交答案,不 ...

  10. python3 基本书写规范

    一.缩进在类.函数定义完成后需要接着写子代码快需要在定义完成后加上: 缩进格式为首字母开始空格4个位置(取消了大括号以冒号代替子模块)例: class pop: #类的定义方式 def pip: #函 ...