0 ,别忘了引包 :

import spark.implicits._

1 ,SparkSQL 介绍 :

  1. SparkSQL 脱离了 Hive 的限制。
  2. SparkSQL 支持查询原生的 RDD。 RDD 是 Spark 平台的核心概念,是 Spark 能够高效的处理大数据的各种场景的基础。
  3. 能够在 Scala 中写 SQL 语句。支持简单的 SQL 语法检查,能够在 Scala 中写 Hive 语句访问 Hive数据,并将结果取回作为 RDD 使用。

2 ,spark on Hive ( 常用 ) 和 Hive on Spark

  1. Spark on Hive: Hive 只作为储存角色,Spark 负责 sql 解析优化,执行。
    1 ,存储 : hive
    2 ,sql 解析 : spark
    3 ,执行查询操作 : spark
  2. Hive on Spark:Hive 即作为存储又负责 sql 的解析优化,Spark 负责执行。
    1 ,存储 : hive
    2 ,sql 解析 : hive
    3 ,执行查询操作 : spark

3 ,DataFrame

  1. DataFrame 也是一个分布式数据容器。
    1 ,与 RDD 类似,然而 DataFrame 更像传统数据库的二维表格,除了数据以外,还掌握数据的结构信息,即 schema。
    2 ,与 Hive 类似,DataFrame 也支持嵌套数据类型(struct、array和map)
    3 ,从 API 易用性的角度上 看, DataFrame API 提供的是一套高层的关系操作,比函数式的 RDD API 要更加友好,门槛更低。
  2. DataFrame 的底层封装的是 RDD,只不过 RDD 的泛型是 Row 类型。

4 ,SparkSQL 的数据源,可以是 :

  1. JSON 类型的字符串
  2. JDBC
  3. Parquent
  4. Hive
  5. HDFS

5 ,SparkSQL 底层架构 :

首先拿到 sql 后解析一批未被解决的逻辑计划,再经过分析得到分析后的逻辑计划,再经过一批优化规则转换成一批最佳优化的逻辑计划,再经过 SparkPlanner 的策略转化成一批物理计划,随后经过消费模型转换成一个个的 Spark 任务执行。

6 ,谓词下推(predicate Pushdown)

  1. spark 采用的是后者,先过滤,再合并。

7 ,spark 读取 json 格式文件 : json 文件 ( json )

{"name":"zhangsan","age":20}
{"name":"lisi"}
{"name":"wangwu","age":18}
{"name":"a","age":19}
{"name":"zhangsan1","age":20}
{"name":"lisi1"}
{"name":"wangwu1","age":18}
{"name":"a1","age":19}
{"name":"zhangsan2","age":20}
{"name":"lisi2"}
{"name":"wangwu2","age":18}
{"name":"a2","age":19}
{"name":"zhangsan3","age":20}
{"name":"lisi3"}
{"name":"wangwu13","age":18}
{"name":"a3","age":19}
{"name":"zhangsan4","age":20}
{"name":"lisi4"}
{"name":"wangwu4","age":18}
{"name":"a4","age":19}

8 ,sparkSql 读 json 数据 : ( 表数据,表信息 )

package day04

import org.apache.spark.sql.{DataFrame, SparkSession}

object SparkSqlTest {
    def main(args: Array[String]): Unit = {
        //  spark 上下文
        val spark: SparkSession = SparkSession.builder().appName("testSql").master("local").getOrCreate()
        //  RDD[Rows]
        val frame: DataFrame = spark.read.json("./data/json")
        //  打印数据信息
        frame.show(10)
        //  表信息
        frame.printSchema()
        spark.close()
    }
}

9 ,拿出来 10 条数据 :

val rows: Array[Row] = frame.take(10)

10 ,select : select name,age from tablename :

val df01: DataFrame = df.select(df.col("name"),df.col("age"))

11 ,判断 :

  1. 代码 :
import spark.implicits._
val df01: DataFrame = df.select(df.col("name").equalTo("zhangsan"),df.col("age"))
  1. 结果 :

12 ,where :

import spark.implicits._
val df1: Dataset[Row] = df.select(df.col("name"),df.col("age")).filter("name='zhangsan' or name='zhangsan1'")

13 ,排序 :

import spark.implicits._
val df1: Dataset[Row] = df.select(df.col("name"),df.col("age")).sort($"name".desc,$"age".asc)

14 ,select + 别名 + 排序 :

import spark.implicits._
val df1: Dataset[Row] = df.select($"name".alias("n"),$"age".alias("a")).sort($"a".asc)

15 ,select … where …

import spark.implicits._
val df1: Dataset[Row] = df.select($"name",$"age").where($"name".equalTo("zhangsan"))

16 ,分组,count :

import spark.implicits._
val df1: DataFrame = df.select($"name",$"age").groupBy("name").count()

17 ,分组 ,排序 ,topN :

package day04

import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}

object SparkSqlTest {
    def main(args: Array[String]): Unit = {
        //  spark 上下文
        val spark: SparkSession = SparkSession.builder().appName("testSql").master("local").getOrCreate()
        //  RDD[Rows]
        val df: DataFrame = spark.read.json("./data/json")
        import spark.implicits._
        val rows: Array[Row] = df.select($"name",$"age").groupBy("name").count().sort($"count".desc).take(3)
        rows.foreach(println)
        spark.close()
    }
}

18 ,select name,age from table where age > 18

package day04

import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}

object SparkSqlTest {
    def main(args: Array[String]): Unit = {
        //  spark 上下文
        val spark: SparkSession = SparkSession.builder().appName("testSql").master("local").getOrCreate()
        //  RDD[Rows]
        val df: DataFrame = spark.read.json("./data/json")
        import spark.implicits._
        val res: Dataset[Row] = df.select($"name",$"age").where($"age">18)
        res.show()
        spark.close()
    }
}

19 ,直接写 sql :

package day04

import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}

object SparkSqlTest {
    def main(args: Array[String]): Unit = {
        //  spark 上下文
        val spark: SparkSession = SparkSession.builder().appName("testSql").master("local").getOrCreate()
        //  RDD[Rows]
        val df: DataFrame = spark.read.json("./data/json")
        df.createOrReplaceTempView("person")
        val df1: DataFrame = spark.sql("select name,age from person where age > 18")
        df1.show()
        spark.close()
    }
}

20 ,临时视图( 常用 ),全局视图 :

  1. 临时视图 : df.createOrReplaceTempView(“person”)
    不跨会话
  2. 全局视图 : df.createOrReplaceGlobalTempView(“person”)
    夸会话
  3. 跨会话例子 : 不常用
package day04

import org.apache.spark.sql.{DataFrame, Dataset, Row, SparkSession}

object SparkSqlTest {
    def main(args: Array[String]): Unit = {
        //  spark 上下文
        val spark: SparkSession = SparkSession.builder().appName("testSql").master("local").getOrCreate()
        //  RDD[Rows]
        val df: DataFrame = spark.read.json("./data/json")
        df.createOrReplaceGlobalTempView("person")
        spark.sql("select name,age from global_temp.person where age > 18").show()
        val spark2: SparkSession = spark.newSession()
        spark2.sql("select name,age from global_temp.person where age > 18").show()
    }
}
  1. 注意 : 前一次如果不跨会话,就认为是局部表了,以后也跨不了会话了 。

21 ,总结 :

  1. 列的前后,谁在前,谁在后 :
    ascII 码排序。
  2. 列类型 : 自动推断。
  3. 创建临时表 : 2 种。
  4. df.show : 默认显示前 20 条数据。

22 ,彩蛋 : 嵌套 json

  1. json 数据 : jsonQian
{"name":"zhangsan","age":20,"info":{"a":1,"b":2}}
{"name":"lisi","info":{"c":3,"d":4}}
{"name":"wangwu","age":19,"info":{"e":5,"f":6}}
{"name":"a","age":18,"info":{"g":7,"h":8}}
{"name":"zhangsan","age":17,"info":{"i":9,"j":0}}
{"name":"lisi","info":{"l":11,"m":12}}
{"name":"wangwu","age":16,"info":{"n":1,"p":"o"}}
  1. 代码 :
package day04

import org.apache.spark.sql.{DataFrame, SparkSession}

object JsonQianTest {
    def main(args: Array[String]): Unit = {
        //  spark 上下文
        val spark: SparkSession = SparkSession.builder().appName("testSql").master("local").getOrCreate()
        //  RDD[Rows]
        val df: DataFrame = spark.read.json("./data/jsonQian")
        df.createOrReplaceTempView("person")
        spark.sql("select name,age,info.a,info.b from person").show()
        spark.stop()
    }
}

23 ,json 数组 :

  1. 数据 :
{"name":"zhangsan","age":20,"info":[{"a":1,"b":2},{"a":3,"b":4}]}
{"name":"lisi","info":[{"a":1,"b":2},{"a":3,"b":4}]}
{"name":"wangwu","age":19,"info":[{"a":1,"b":2},{"a":3,"b":4}]}
{"name":"a","age":18,"info":[{"a":1,"b":2},{"a":3,"b":4}]}
{"name":"zhangsan","age":17,"info":[{"a":1,"b":2},{"a":3,"b":4}]}
{"name":"lisi","info":[{"a":1,"b":2},{"a":3,"b":4}]}
{"name":"wangwu","age":16,"info":[{"a":1,"b":2},{"a":3,"b":4}]}
  1. 代码 :
spark.sql("select name,age,info[0].a from person").show()