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

时间:2018-01-30 06:53:01

标签: scala apache-spark apache-spark-sql spark-dataframe

我有以下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

2 个答案:

答案 0 :(得分:1)

一种方法是将日期转换为unixtime,进行聚合,然后再将其转换回来。可以分别使用unix_timestampfrom_unixtime执行与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|
+---+---+-----+----------+

答案 1 :(得分:-2)

在两个字段上执行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"))