天天看點

Spark學習--SparkSQL04

聚合

使用 functions 函數進行聚合

import org.apache.spark.sql.functions._

val groupedDF: RelationalGroupedDataset = pmDF.groupBy('year)

groupedDF.agg(avg('pm) as "pm_avg")
  .orderBy('pm_avg)
  .show()      

使用 RelationalGroupedDataset 的 API 進行聚合

groupedDF.avg("pm")
  .orderBy('pm_avg)
  .show()

groupedDF.max("pm")
  .orderBy('pm_avg)
  .show()      

多元聚合

rollup(A,B)

rollup 就相當于先按照 A, B 進行聚合, 後按照 A進行聚合, 最後對整個資料集進行聚合, 在按照 A 聚合時, B 列值為 null, 聚合整個資料集的時候, 除了聚合列, 其它列值都為 null。結果集中有三種資料形式: A B C, A null C, null null C

cube(A,B)

結果集中有四種資料形式: A B C, A null C, null null C, null B C

連接配接

連接配接類型 類型字段 解釋
交叉連接配接

cross

交叉連接配接就是笛卡爾積, 就是兩個表中所有的資料兩兩結對

交叉連接配接是一個非常重的操作, 在生産中, 盡量不要将兩個大資料集交叉連接配接, 如果一定要交叉連接配接, 也需要在交叉連接配接後進行過濾, 優化器會進行優化

Spark學習--SparkSQL04

SQL

 語句
select * from person cross join cities           

Dataset

 操作
person.crossJoin(cities)
  .where(person.col("cityId") === cities.col("id"))
  .show()           
内連接配接

inner

内連接配接就是按照條件找到兩個資料集關聯的資料, 并且在生成的結果集中隻存在能關聯到的資料
Spark學習--SparkSQL04

SQL

select * from person inner join cities on person.cityId = cities.id           

Dataset

person.join(right = cities,
  joinExprs = person("cityId") === cities("id"),
  joinType = "inner")
  .show()           
全外連接配接

outer

full

fullouter

内連接配接和外連接配接的最大差別, 就是内連接配接的結果集中隻有可以連接配接上的資料, 而外連接配接可以包含沒有連接配接上的資料, 根據情況的不同, 外連接配接又可以分為很多種, 比如所有的沒連接配接上的資料都放入結果集, 就叫做全外連接配接
Spark學習--SparkSQL04

SQL

select * from person full outer join cities on person.cityId = cities.id           

Dataset

person.join(right = cities,
  joinExprs = person("cityId") === cities("id"),
  joinType = "full") // "outer", "full", "full_outer"
  .show()           
左外連接配接

leftouter

left

左外連接配接是全外連接配接的一個子集, 全外連接配接中包含左右兩邊資料集沒有連接配接上的資料, 而左外連接配接隻包含左邊資料集中沒有連接配接上的資料
Spark學習--SparkSQL04

SQL

select * from person left join cities on person.cityId = cities.id           

Dataset

person.join(right = cities,
  joinExprs = person("cityId") === cities("id"),
  joinType = "left") // leftouter, left
  .show()           

LeftAnti

leftanti

LeftAnti

 是一種特殊的連接配接形式, 和左外連接配接類似, 但是其結果集中沒有右側的資料, 隻包含左邊集合中沒連接配接上的資料
Spark學習--SparkSQL04

SQL

select * from person left anti join cities on person.cityId = cities.id           

Dataset

person.join(right = cities,
  joinExprs = person("cityId") === cities("id"),
  joinType = "left_anti")
  .show()           

LeftSemi

leftsemi

和 

LeftAnti

 恰好相反, 

LeftSemi

 的結果集也沒有右側集合的資料, 但是隻包含左側集合中連接配接上的資料
Spark學習--SparkSQL04

SQL

select * from person left semi join cities on person.cityId = cities.id           

Dataset

person.join(right = cities,
  joinExprs = person("cityId") === cities("id"),
  joinType = "left_semi")
  .show()           
Spark學習--SparkSQL04

SQL

select * from person right join cities on person.cityId = cities.id           

Dataset

person.join(right = cities,
  joinExprs = person("cityId") === cities("id"),
  joinType = "right") // rightouter, right
  .show()           

繼續閱讀