Azure Databricks:STRING类型日期列转DATE及获取最新日期方法
解决方案
针对你遇到的字符串日期排序问题,以下是Azure Databricks中SQL和Scala两种环境下的解决办法:
SQL 方案
1. 查询时临时转换日期类型
直接在查询中使用to_date()函数将字符串转为日期类型,再筛选最新日期。必须指定与字符串匹配的日期格式(比如yyyy-MM-dd、MM/dd/yyyy等),否则转换会失效:
SELECT * FROM final_table WHERE to_date(Period_Ending_Date, 'yyyy-MM-dd') = ( SELECT MAX(to_date(Period_Ending_Date, 'yyyy-MM-dd')) FROM final_table )
如果存在格式不统一的情况,用try_to_date()替代,转换失败的记录会返回null,可额外过滤掉无效数据:
SELECT * FROM final_table WHERE try_to_date(Period_Ending_Date, 'yyyy-MM-dd') = ( SELECT MAX(try_to_date(Period_Ending_Date, 'yyyy-MM-dd')) FROM final_table ) AND try_to_date(Period_Ending_Date, 'yyyy-MM-dd') IS NOT NULL
2. 永久修改表列类型(Delta表适用)
如果是Delta表,可直接修改列类型为DATE,后续查询无需重复转换:
-- 修改列类型,指定日期格式 ALTER TABLE final_table ALTER COLUMN Period_Ending_Date TYPE DATE USING to_date(Period_Ending_Date, 'yyyy-MM-dd'); -- 修改后直接用原逻辑查询即可 SELECT * FROM final_table WHERE Period_Ending_Date = (SELECT MAX(Period_Ending_Date) FROM final_table)
如果是非Delta表,可重新创建表时完成转换:
CREATE OR REPLACE TABLE final_table AS SELECT *, to_date(Period_Ending_Date, 'yyyy-MM-dd') AS Period_Ending_Date FROM original_source_table; -- 替换为你从ADLS读取的原表/视图
Scala 方案
使用DataFrame API完成日期转换与筛选:
1. 转换后直接筛选
import org.apache.spark.sql.functions._ // 从ADLS读取文件(示例为CSV,根据实际格式调整) val rawDF = spark.read .option("header", "true") .csv("abfss://container@storageaccount.dfs.core.windows.net/path/to/files") // 转换日期列,指定匹配的格式 val dateDF = rawDF.withColumn("Period_Ending_Date", to_date(col("Period_Ending_Date"), "yyyy-MM-dd")) // 获取最新日期并筛选 val latestDate = dateDF.agg(max("Period_Ending_Date")).first().getDate(0) val resultDF = dateDF.filter(col("Period_Ending_Date") === latestDate) // 输出或保存结果 resultDF.show()
2. 用窗口函数直接筛选
无需单独查询最大日期,通过窗口函数标记最新日期的记录:
import org.apache.spark.sql.functions._ import org.apache.spark.sql.expressions.Window val rawDF = spark.read .option("header", "true") .csv("abfss://container@storageaccount.dfs.core.windows.net/path/to/files") val dateDF = rawDF.withColumn("Period_Ending_Date", to_date(col("Period_Ending_Date"), "yyyy-MM-dd")) // 按日期降序排名,取排名第一的记录 val windowSpec = Window.orderBy(col("Period_Ending_Date").desc) val resultDF = dateDF .withColumn("rank", row_number().over(windowSpec)) .filter(col("rank") === 1) .drop("rank") resultDF.show()
内容的提问来源于stack exchange,提问作者Nilesh Patel
相关产品推荐
相关产品推荐

