Spark SQL常用表达式示例
版权声明:本文为博主原创文章,未经博主允许不得转载。
手动码字不易,请大家尊重劳动成果,谢谢
本文使用spark-shell来演示我平时常用的一些Spark SQL表达式,来帮助大家更好体会Spark SQL的使用方式。
所有可用函数可以使用这篇文章中的方法进行查看:https://blog.youkuaiyun.com/wang_wbq/article/details/79672012
以下为官方文档中取DataFrame中的其中几列、进行简单运算、过滤、分组合并的示例,以使大家对select
、filter
、groupBy
等方法有个初步的认识。
// This import is needed to use the $-notation
import spark.implicits._
// Print the schema in a tree format
df.printSchema()
// root
// |-- age: long (nullable = true)
// |-- name: string (nullable = true)
// Select only the "name" column
df.select("name").show()
// +-------+
// | name|
// +-------+
// |Michael|
// | Andy|
// | Justin|
// +-------+
// Select everybody, but increment the age by 1
df.select($"name", $"age" + 1).show()
// +-------+---------+
// | name|(age + 1)|
// +-------+---------+
// |Michael| null|
// | Andy| 31|
// | Justin| 20|
// +-------+---------+
// Select people older than 21
df.filter($"age" > 21).show()
// +---+----+
// |age|name|
// +---+----+
// | 30|Andy|
// +---+----+
// Count people by age
df.groupBy("age").count().show()
// +----+-----+
// | age|count|
// +----+-----+
// | 19| 1|
// |null| 1|
// | 30| 1|
// +----+-----+
1、字符串过滤
这种方式可以使用SQL查询中的LIKE语法
scala> df.show
+-------+---+
| name|age|
+-------+---+
| Mike| 4|
|Michael| 6|
| Peter| 3|
| Andy| 5|
+-------+---+
scala> df.filter("like(name, 'M%')").show
+-------+---+
| name|age|
+-------+---+
| Mike| 4|
|Michael| 6|
+-------+---+
//较老的版本只支持此种方式
scala> df.filter("name LIKE 'M%'").show
+-------+---+
| name|age|
+-------+---+
| Mike| 4|
|Michael| 6|
+-------+---+
2、字符串分割与数组取值
我们可以使用split(str, reg)
函数来分割字符串,注意第二个参数是正则表达式
数组取值有两种方式,一种是在字符串表达式中使用[序号]
,或者在代码中使用Column
类的apply
方法(序号)
。简而言之就是在字符串里用方括号,在字符串外用圆括号
scala> df.show
+-------------------+-----+
| time|value|
+-------------------+-----+
|2018-01-01 09:00:00| 1|
|2018-01-01 09:00:00| 2|
|2018-01-01 10:00:00| 3|
|2018-01-03 11:00:00| 4|
|2018-01-01 12:00:00| 5|
|2018-01-06 13:00:00| 6|
|2018-01-09 14:00:00| 7|
|2018-01-08 15:00:00| 8|
|2018-01-02 09:00:00| 1|
|2018-01-02 09:00:00| 2|
|2018-01-03 10:00:00| 3|
|2018-01-07 11:00:00| 4|
|2018-01-06 12:00:00| 5|
|2018-01-09 13:00:00| 6|
|2018-01-04 14:00:00| 7|
|2018-01-02 15:00:00| 8|
+-------------------+-----+
scala> df.select(col("*"), expr("split(time, ' ')[0]").as("day")).show
+-------------------+-----+----------+
| time|value| day|
+-------------------+-----+----------+
|2018-01-01 09:00:00| 1|2018-01-01|
|2018-01-01 09:00:00| 2|2018-01-01|
|2018-01-01 10:00:00| 3|2018-01-01|
|2018-01-03 11:00:00| 4|2018-01-03|
|2018-01-01 12:00:00| 5|2018-01-01|
|2018-01-06 13:00:00| 6|2018-01-06|
|2018-01-09 14:00:00| 7|2018-01-09|
|2018-01-08 15:00:00| 8|2018-01-08|
|2018-01-02 09:00:00| 1|2018-01-02|
|2018-01-02 09:00:00| 2|2018-01-02|
|2018-01-03 10:00:00| 3|2018-01-03|
|2018-01-07 11:00:00| 4|2018-01-07|
|2018-01-06 12:00:00| 5|2018-01-06|
|2018-01-09 13:00:00| 6|2018-01-09|
|2018-01-04 14:00:00| 7|2018-01-04|
|2018-01-02 15:00:00| 8|2018-01-02|
+-------------------+-----+----------+
scala> df.select(col("*"), expr("split(time, ' ')")(0).as("day")).show
+-------------------+-----+----------+
| time|value| day|
+-------------------+-----+----------+
|2018-01-01 09:00:00| 1|2018-01-01|
|2018-01-01 09:00:00| 2|2018-01-01|
|2018-01-01 10:00:00| 3|2018-01-01|
|2018-01-03 11:00:00| 4|2018-01-03|
|2018-01-01 12:00:00| 5|2018-01-01|
|2018-01-06 13:00:00| 6|2018-01-06|
|2018-01-09 14:00:00| 7|2018-01-09|
|2018-01-08 15:00:00| 8|2018-01-08|
|2018-01-02 09:00:00| 1|2018-01-02|
|2018-01-02 09:00:00| 2|2018-01-02|
|2018-01-03 10:00:00| 3|2018-01-03|
|2018-01-07 11:00:00| 4|2018-01-07|
|2018-01-06 12:00:00| 5|2018-01-06|
|2018-01-09 13:00:00| 6|2018-01-09|
|2018-01-04 14:00:00| 7|2018-01-04|
|2018-01-02 15:00:00| 8|2018-01-02|
+-------------------+-----+----------+
3、字符串替换
字符串替换共有两种方式,regexp_replace
与replace
。从名字可以看出,regexp_replace
是支持正则表达式的,replace
是普通字符串替换。
scala> df.show
+-------------------+-----+
| time|value|
+-------------------+-----+
|2018-01-01 09:00:00| 1|
|2018-01-01 09:00:00| 2|
|2018-01-01 10:00:00| 3|
|2018-01-03 11:00:00| 4|
|2018-01-01 12:00:00| 5|
|2018-01-06 13:00:00| 6|
|2018-01-09 14:00:00| 7|
|2018-01-08 15:00:00| 8|
|2018-01-02 09:00:00| 1|
|2018-01-02 09:00:00| 2|
|2018-01-03 10:00:00| 3|
|2018-01-07 11:00:00| 4|
|2018-01-06 12:00:00| 5|
|2018-01-09 13:00:00| 6|
|2018-01-04 14:00:00| 7|
|2018-01-02 15:00:00| 8|
+-------------------+-----+
scala> df.select(col("*"), expr("regexp_replace(time, '[-: ]', '@')").as("replace")).show
+-------------------+-----+-------------------+
| time|value| replace|
+-------------------+-----+-------------------+
|2018-01-01 09:00:00| 1|2018@01@01@09@00@00|
|2018-01-01 09:00:00| 2|2018@01@01@09@00@00|
|2018-01-01 10:00:00| 3|2018@01@01@10@00@00|
|2018-01-03 11:00:00| 4|2018@01@03@11@00@00|
|2018-01-01 12:00:00| 5|2018@01@01@12@00@00|
|2018-01-06 13:00:00| 6|2018@01@06@13@00@00|
|2018-01-09 14:00:00| 7|2018@01@09@14@00@00|
|2018-01-08 15:00:00| 8|2018@01@08@15@00@00|
|2018-01-02 09:00:00| 1|2018@01@02@09@00@00|
|2018-01-02 09:00:00| 2|2018@01@02@09@00@00|
|2018-01-03 10:00:00| 3|2018@01@03@10@00@00|
|2018-01-07 11:00:00| 4|2018@01@07@11@00@00|
|2018-01-06 12:00:00| 5|2018@01@06@12@00@00|
|2018-01-09 13:00:00| 6|2018@01@09@13@00@00|
|2018-01-04 14:00:00| 7|2018@01@04@14@00@00|
|2018-01-02 15:00:00| 8|2018@01@02@15@00@00|
+-------------------+-----+-------------------+
scala> df.select(col("*"), expr("replace(time, ':', '@')").as("replace")).show
+-------------------+-----+-------------------+
| time|value| replace|
+-------------------+-----+-------------------+
|2018-01-01 09:00:00| 1|2018-01-01 09@00@00|
|2018-01-01 09:00:00| 2|2018-01-01 09@00@00|
|2018-01-01 10:00:00| 3|2018-01-01 10@00@00|
|2018-01-03 11:00:00| 4|2018-01-03 11@00@00|
|2018-01-01 12:00:00| 5|2018-01-01 12@00@00|
|2018-01-06 13:00:00| 6|2018-01-06 13@00@00|
|2018-01-09 14:00:00| 7|2018-01-09 14@00@00|
|2018-01-08 15:00:00| 8|2018-01-08 15@00@00|
|2018-01-02 09:00:00| 1|2018-01-02 09@00@00|
|2018-01-02 09:00:00| 2|2018-01-02 09@00@00|
|2018-01-03 10:00:00| 3|2018-01-03 10@00@00|
|2018-01-07 11:00:00| 4|2018-01-07 11@00@00|
|2018-01-06 12:00:00| 5|2018-01-06 12@00@00|
|2018-01-09 13:00:00| 6|2018-01-09 13@00@00|
|2018-01-04 14:00:00| 7|2018-01-04 14@00@00|
|2018-01-02 15:00:00| 8|2018-01-02 15@00@00|
+-------------------+-----+-------------------+
scala> df.select(col("*"), expr("regexp_replace(time, '([0-9]{4})-([0-9]{2})-([0-9]{2}) ([0-9]{2}):([0-9]{2}):([0-9]{2})', '$1~$2~$3%$4-$5-$6')").as("replace")).show
+-------------------+-----+-------------------+
| time|value| replace|
+-------------------+-----+-------------------+
|2018-01-01 09:00:00| 1|2018~01~01%09-00-00|
|2018-01-01 09:00:00| 2|2018~01~01%09-00-00|
|2018-01-01 10:00:00| 3|2018~01~01%10-00-00|
|2018-01-03 11:00:00| 4|2018~01~03%11-00-00|
|2018-01-01 12:00:00| 5|2018~01~01%12-00-00|
|2018-01-06 13:00:00| 6|2018~01~06%13-00-00|
|2018-01-09 14:00:00| 7|2018~01~09%14-00-00|
|2018-01-08 15:00:00| 8|2018~01~08%15-00-00|
|2018-01-02 09:00:00| 1|2018~01~02%09-00-00|
|2018-01-02 09:00:00| 2|2018~01~02%09-00-00|
|2018-01-03 10:00:00| 3|2018~01~03%10-00-00|
|2018-01-07 11:00:00| 4|2018~01~07%11-00-00|
|2018-01-06 12:00:00| 5|2018~01~06%12-00-00|
|2018-01-09 13:00:00| 6|2018~01~09%13-00-00|
|2018-01-04 14:00:00| 7|2018~01~04%14-00-00|
|2018-01-02 15:00:00| 8|2018~01~02%15-00-00|
+-------------------+-----+-------------------+
4、结构体数据的索引
由于本节较复杂,为了防止篇幅太长影响阅读体验,因此新开了一个博客来介绍:https://blog.youkuaiyun.com/wang_wbq/article/details/79675522
5、集合数据类型的索引
由于本节较复杂,为了防止篇幅太长影响阅读体验,因此新开了一个博客来介绍:https://blog.youkuaiyun.com/wang_wbq/article/details/79678168
未完待续~~~