2016-04-19 101 views
0

我正在使用Spark 1.3。我想做一些基於日期的計算。在下面的數據集中,對於每個唯一的ID,我想獲取beging_date最大的記錄(最新記錄)。另外,當我從文件讀取數據時,是否應該將它轉換爲TimestampType(import org.apache.spark.sql.types.TimestampType)?SparkSQL日期時間函數

下面是一些示例數據:

ID beging_date END_DATE

1 2016年1月1日20:06:00.0 2016年1月4日20:06:00.0

2 1 /二千○十三分之五20:06:00.0 2016年1月8日20:06:00.0

1 2013年1月6日20:06:00.0 2016年1月18日20:06:00.0

3 2/1/2013 20:06:00.0 2/5/2016 20: 06:00.0

1二零一三年一月二十零日20:06:00.0 20 2016年2月4日:06:00.0

3 2013年3月5日20:06:00.0 2016年3月8日20: 06:00.0

這裏是所期望的輸出:

ID beging_date END_DATE

1二零一三年一月二十零日20:06:00.0 20 2016年2月4日:06:00.0

2 2013年1月5日20:06:00.0 2016年1月8日20:06:00.0

3 2013年3月5日20:06:00.0 2016年3月8日20:06:00.0

回答

1

在處理日期時,我認爲分別討論數據如何存儲在磁盤上或序列化以及如何將它作爲對象存儲在內存中很重要。

將您的日期序列化爲字符串。字符串表示是一個很差的表示;這可能是我在TimestampTypeLongType,甚至DoubleType後面的第4個選擇。分析字符串總是很痛苦。另一方面 - 你的日期已經被串行化爲字符串,你需要/想要改變它嗎?

我會考慮讓原始列完好無損並創建一個更有利於數據消除的新列。

這將我引向下一點 - 您想如何將日期表示爲內存中的對象,從而完全打開您的使用方式。對於像「查找最大值」這樣的操作,最簡單的操作可能是將其轉換爲例如自1970年1月1日以來的毫秒數LongType。幾乎每個與日期相關的對象和函數都可以攝取或吐出一個unix時間戳,所以它們很容易來回轉換。

要將字符串轉換爲TimestampType,需要將它們轉換爲java.sql.Timestamp。我會離開它給你找出確切的格式,但你想要的東西,如:

import java.sql.Timestamp 
import java.text.SimpleDateFormat 

val formatter = new SimpleDateFormat(...) 
val millis_since_1_1_1970 = formatter.parse("1/5/2013 20:06:00.0").getTime 
val timestamp = new java.sql.Timestamp(millis_since_1_1_1970) 

就像我說的,你可以只是停止millis_since_1_1_1970後,並使用該Long值作爲比較值。出於你的目的,它會工作