scala - 使用scala在spark-sql中的其他列检索最大日期组
问题描述
环境 - spark-3.0.1-bin-hadoop2.7、ScalaLibraryContainer 2.12.3、Scala、SparkSQL、eclipse-jee-oxygen-2-linux-gtk-x86_64
我有一个 csv 文件,它有 3 列,数据类型为:String、Long、Date。我想按字符串的第一列分组并检索最大日期值。
为此,我从文本文件创建了 Person 对象的 RDD,并将其转换为数据框“peopleDF”。将数据框注册为临时视图。我使用 spark 提供的 sql 方法运行以下 sql 语句。
val maxDateDF = spark.sql("SELECT name, max(birthDate) maxDate FROM people group by name")
但它没有给出名称的正确最大日期。
我的样本数据如下
Michael, 29,01/03/1992
Justin, 19,01/05/2002
Ben Stokes, 29,01/07/1992
Justin, 18,01/08/2003
Ben Stokes, 29,01/07/1993
Ben Stokes, 29,30/06/1993
如何按其他字段名称检索最大日期值组?
package org.apache.spark.examples.sql
import org.apache.spark.sql.Row
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.types._
import java.sql.Date
import breeze.linalg.max
object SparkSQLExample1 {
case class Person(name: String, age: Long, birthDate: String)
def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().appName("Spark SQL basic example")
.config("spark.master", "local").getOrCreate();
import spark.implicits._
runInferSchemaExample(spark);
spark.stop()
}
private def runInferSchemaExample(spark: SparkSession): Unit = {
import spark.implicits._
val peopleDF = spark.sparkContext
.textFile("examples/src/main/resources/people.txt")
.map(_.split(","))
.map(attributes => Person(attributes(0), attributes(1).trim.toInt,attributes(2)))
.toDF()
peopleDF.groupBy("age").count().show();
peopleDF.groupBy("name").avg("age").show();
peopleDF.createOrReplaceTempView("people")
implicit val mapEncoder = org.apache.spark.sql.Encoders.kryo[Map[String, Any]]
val maxDateDF = spark.sql("SELECT name, max(birthDate) maxDate FROM people group by name")
maxDateDF.map(teenager => teenager.getValuesMap[Any](List("name", "maxDate"))).collect().foreach(println)
}
}
解决方案
应用于max
字符串类型列不会为您提供最大日期。您需要先将其转换为日期类型列:
val maxDateDF = spark.sql("SELECT name, max(to_date(birthDate, 'dd/MM/yyyy')) maxDate FROM people group by name")
如果您希望保留原始日期格式,可以使用以下方法将其转换回字符串date_format
:
val maxDateDF = spark.sql("SELECT name, date_format(max(to_date(birthDate, 'dd/MM/yyyy')), 'dd/MM/yyyy') maxDate FROM people group by name")
推荐阅读
- java - AWS 开发工具包在使用 Java 8 时抛出 java.security.InvalidAlgorithmParameterException
- java - 新的 JFrame 在风险游戏克隆中偶尔会出现空白
- wpf - 激活后,如何从我的复选框中更改 DataGridHeader 的颜色?
- ios - 在 `publisher.receive(on: backgroundQueue)` 之后不调用`Sink.receiveValue`
- python - 仅转换每列的第一个和最后一个填充值之间的 nans
- wpf - 如何将面板的数据上下文绑定到 XAML 中的父对象?
- angular - 在 Angular 中获取自动完成占位符和 formControlName
- objective-c - 用于匹配只需要以有效序列开始的模式的正则表达式
- android - Google Play 控制台中未列出的云项目 > Play 游戏服务设置
- python - 计算连续时间段的天数(Python,日期时间)