在Spark SQL中使用Group By Date进行聚合

gal*_*lex 4 sql group-by aggregation apache-spark

我有一个RDD包含一个名为time long类型的时间戳:

root
 |-- id: string (nullable = true)
 |-- value1: string (nullable = true)
 |-- value2: string (nullable = true)
 |-- time: long (nullable = true)
 |-- type: string (nullable = true)
Run Code Online (Sandbox Code Playgroud)

我试图将value1,value2和time分组为YYYY-MM-DD.我试图按强制分组(时间为日期),但后来我收到以下错误:

Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.apache.spark.deploy.worker.DriverWrapper$.main(DriverWrapper.scala:40)
    at org.apache.spark.deploy.worker.DriverWrapper.main(DriverWrapper.scala)
Caused by: java.lang.RuntimeException: [1.21] failure: ``DECIMAL'' expected but identifier Date found
Run Code Online (Sandbox Code Playgroud)

这是否意味着没有办法按日期分组?我甚至试图添加另一个级别的转换以将其作为String:

cast(cast(time as Date) as String)
Run Code Online (Sandbox Code Playgroud)

哪个返回相同的错误.

我已经读过,我可能在RDD上使用了可能的aggregateByKey,但我不明白如何将它用于几列并将其转换为YYYY-MM-DD字符串.我该怎么办?

gal*_*lex 5

我通过添加这些功能解决了这个问题:

def convert( time:Long ) : String = {
  val sdf = new java.text.SimpleDateFormat("yyyy-MM-dd")
  return sdf.format(new java.util.Date(time))
}
Run Code Online (Sandbox Code Playgroud)

并将其注册到sqlContext中,如下所示:

sqlContext.registerFunction("convert", convert _)
Run Code Online (Sandbox Code Playgroud)

然后我可以按日期分组:

select * from table convert(time)
Run Code Online (Sandbox Code Playgroud)