转载自本人语雀
https://www.yuque.com/docs/share/f657347e-6a89-469b-ae54-52e678060ba1?# 《SparkSql的基础操作》
● Spark SQL 是 Spark 处理数据的一个模块
● 专门用来处理结构化数据的模块
● 与基础 RDD(强类型,无结构) 的 API 不同,Spark SQL 中提供的接口将提供给更多关于结 构化数据和计算的信息,并针对这些信息,进行额外的处理优化
●DataFrame=RDD[Row]+Schema
○Row表示每行数据,抽象的。并不知道每行Row数据有多少列
○schema是数据结构的说明
○相当于DataSet的特殊类型,DataSet[Row]
●DataSet
○有结构,强类型
○多种数据类型,类型可以是对象
●spark读取hive表
●有的能读,有的不能
○区别
■能读外表
■内表不行,有的是事务表
○本质
■spark无法读取到事务表
构建SparkSql的两种配置
常用api
●SparkSql 针对数据进行格式转换
○api
■withColumn(name:String,col:Column):DataFrame
●修改DF列的API
■col(columnName:String):Column
●获取列
■df(columnName:String):Column
●获取列
○修改类型的方式
■通过withColumn直接修改结构
■通过select查询的时候转换
weiboDF.withColumn("commentCount", col("commentCount").cast(IntegerType))
.select(
weiboDF("content"),
col("commentCount").cast(IntegerType).as("num")
)
.orderBy(desc("num")).show()
○lit
■创建一个常量列
resultDF
.select(
concat(
col("content"),
lit("\001"),
col("commentCount"),
lit("\001"),
col("rank")
)
)
.write
.text(output + "4")
一个groupBy对应多个聚集函数
■使用agg的api才能写多个聚合函数
df.groupBy("source")
.agg(
sum("commentCount").as("total"),
max("commentCount").as("maxNum"),
count(lit(1)).as("num")
)
.orderBy(desc("total"))
.show()
数据分析函数
df
.groupBy("source", "userId")
.sum("commentCount")
.select(
col("source"),
col("userId"),
col("sum(commentCount)").as("total"),
(rank() over (Window.partitionBy("source").orderBy(desc("sum(commentCount)")))).as("rank")
)
.where("rank < 4")
.show()
df( DataFrame )类型和rdd类型的互相转换
df转换为rdd
val jsonPath = "D:\\Users\\BOSS\\IdeaProjects\\scala_java\\data\\input_weibo.json"
val df= spark.read.json(jsonPath)
val rdd: RDD[Row]=df.rdd
rdd.foreach(Row=>
println(Row.getAs("content"))
)
rdd转换为df
○rdd相比于df是缺少结构的,所以我们需要创建一个结构,给rdd拼上
○其次就是对rdd处理成Row的类型并把每个字段分开分开
○最后创建df对象,使用spark的api把他们拼接上
// 1. 需要创建一个结构
val struct = StructType(
List(
StructField("stdNo", StringType),
StructField("name", StringType),
StructField("classId", IntegerType),
StructField("className", StringType)
)
)
// 2. 把rdd的类型转成Row的类型
//法一
val rowRdd: RDD[Row] = rdd.map(str => {
val strArr = str.split("\\s+")
Row(strArr(0), strArr(1), strArr(2), strArr(3))
})
//简化法二
val rowRdd = rdd
.map(_.split("\\s+"))
.map(arr => Row(arr(0), arr(1), arr(2).toInt, arr(3)))
// 3. 创建DF
val df = spark.createDataFrame(rowRdd, struct)
df.printSchema()
df.show()