You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spark SQL中获取指定月份最近一次出现数据的最简方法及可读SQL编写方案

解决Spark SQL中获取指定月份最近一次数据的最简可读写法

嘿,我来帮你搞定这个问题!首先你之前的SQL语句跑不起来,核心原因是CASE语句缺少了END关键字——这是Spark SQL的语法要求,必须用END来闭合CASE逻辑,不然解析器会直接报错。

接下来给你两种高可读性的实现方式,完美匹配你的需求:输入一个月份,自动匹配最近一次出现该月份的年份(当前年或前一年),筛选对应数据。

方式一:直接构造目标月份(最直观推荐)

这种写法通过构造目标月份的起始日期,直接和DateF的月份起始做匹配,逻辑清晰直白,不容易出错:

-- 把@target_month替换成你需要的月份数字(比如11代表11月)
SELECT *
FROM your_table
WHERE date_trunc('month', DateF) = 
  date_trunc('month',
    make_date(
      -- 判断目标月份是否晚于当前月份,是的话取前一年,否则取当前年
      CASE WHEN @target_month > month(current_date()) THEN year(current_date()) - 1 ELSE year(current_date()) END,
      @target_month,
      1
    )
  )

逻辑拆解:

  1. make_date():根据计算出的年份、目标月份,生成该月份的第一天(比如2023-11-01)
  2. date_trunc('month', ...):把日期统一截断到月份起始,这样只要DateF落在目标月份里,截断后就会和目标日期完全相等
  3. 整个WHERE条件清晰表达了“筛选目标月份对应年份的所有数据”的核心需求

方式二:拆分年月比较(兼容旧版Spark)

如果你使用的Spark版本不支持make_date()(比如2.x早期版本),可以用拆分年月的方式,同时修正你原来的CASE语法问题:

-- 把@target_month替换成目标月份
SELECT *
FROM your_table
WHERE month(DateF) = @target_month
  AND year(DateF) = CASE 
    WHEN @target_month > month(current_date()) THEN year(current_date()) - 1 
    ELSE year(current_date()) 
  END -- 这里必须加END,就是你之前漏掉的关键部分!

关键修正说明:

你之前的代码就是少了END,导致CASE语句不完整,Spark无法正常解析。加上END后,语法完全合规,逻辑也能按预期运行。

额外优化:如果需要取该月份的最新单条数据

如果你的需求是获取目标月份里的最新一条数据,可以在上面的基础上加上排序和限制:

SELECT *
FROM your_table
WHERE date_trunc('month', DateF) = 
  date_trunc('month',
    make_date(
      CASE WHEN @target_month > month(current_date()) THEN year(current_date()) - 1 ELSE year(current_date()) END,
      @target_month,
      1
    )
  )
ORDER BY DateF DESC
LIMIT 1

这样就能拿到目标月份里时间最晚的那条记录啦。

内容的提问来源于stack exchange,提问作者Lord_JABA

火山引擎 最新活动