如何从列出的日期中获取最新日期以及总数?

How to get the latest date from listed dates along with the total count?

我有下面的 DataFrame,它有不同日期的键,我想显示其中的最新日期以及每个键-id 对的计数。

输入数据如下:

id  key  date 
11  222  1/22/2017
11  222  1/22/2015
11  222  1/22/2016 
11  223  9/22/2017 
11  223  1/22/2010 
11  223  1/22/2008

我试过的代码:

val counts = df.groupBy($"id",$"key").count()

我得到以下输出,

id  key  count 
11  222   3
11  223   3

但是,我希望输出如下所示:

id  key  count maxDate 
11  222   3    1/22/2017 
11  223   3    9/22/2017

一种方法是将日期转换为 unixtime,进行聚合,然后再将其转换回来。这种与 unixtime 之间的转换可以分别使用 unix_timestampfrom_unixtime 执行。当日期为unixtime时,可以通过查找最大值来选择最晚的日期。这种方法唯一可能的缺点是必须明确给出日期格式。

val dateFormat = "MM/dd/yyyy"

val df2 = df.withColumn("date", unix_timestamp($"date", dateFormat))
  .groupBy($"id",$"key").agg(count("date").as("count"), max("date").as("maxDate"))
  .withColumn("maxDate", from_unixtime($"maxDate", dateFormat))

哪个会给你:

+---+---+-----+----------+
| id|key|count|   maxDate|
+---+---+-----+----------+
| 11|222|    3|01/22/2017|
| 11|223|    3|09/22/2017|
+---+---+-----+----------+

对两个字段执行 agg

df.groupBy($"id", $"key").agg(count($"date"), max($"date"))

输出:

+---+---+-----------+-----------+
| _1| _2|count(date)|  max(date)|
+---+---+-----------+-----------+
| 11|222|          3|  1/22/2017|
| 11|223|          3|  9/22/2017|
+---+---+-----------+-----------+

编辑:另一个答案中提出的as选项也很不错。

编辑:以下评论属实。您需要转换为正确的日期格式。您可以检查转换为时间戳的其他答案或使用 udf

import java.text.SimpleDateFormat
import org.apache.spark.sql.{SparkSession, functions}

val  simpleDateFormatOriginal:SimpleDateFormat = new SimpleDateFormat("MM/dd/yyyy")
val  simpleDateFormatDestination:SimpleDateFormat = new SimpleDateFormat("yyyy/MM/dd")


val toyyyymmdd = (s:String) => {
  simpleDateFormatDestination.format(simpleDateFormatOriginal.parse(s))
}

val toddmmyyyy = (s:String) => {
  simpleDateFormatOriginal.format(simpleDateFormatDestination.parse(s))
}

val toyyyymmddudf = functions.udf(toyyyymmdd)
val toddmmyyyyyudf = functions.udf(toddmmyyyy)


df.withColumn("date", toyyyymmddudf($"date"))
 .groupBy($"id", $"key")
 .agg(count($"date"), max($"date").as("maxDate"))
 .withColumn("maxDate", toddmmyyyyyudf($"maxDate"))