You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

获取每月1日各ID对应col2列最新值的SQL查询需求

解决方案:获取每个ID每月1日对应的最新col2值

看起来你需要的是每个ID在指定月份(2019年1-4月)的每月1日,对应到该日期之前最后一次修改的col2值,没有修改记录的话返回NULL。我来给你拆解思路并提供可行的SQL方案:

核心思路

  1. 先生成你需要的目标日期范围:2019年1月1日到4月1日的每月第一天。
  2. 把所有唯一ID和这些日期做组合,确保每个ID都能覆盖所有目标月份。
  3. 对每个「ID+每月1日」的组合,找到该日期之前(不含该日期之后)最新的修改记录,提取对应的col2;如果没有符合条件的记录,返回NULL。

通用SQL实现(以PostgreSQL为例)

-- 步骤1:生成目标月份的第一天
WITH target_dates AS (
    SELECT DATE '2019-01-01' AS month_start
    UNION ALL
    SELECT (month_start + INTERVAL '1 month')::DATE
    FROM target_dates
    WHERE month_start < DATE '2019-04-01'
),
-- 步骤2:生成所有ID和目标日期的组合
all_id_month AS (
    SELECT DISTINCT t.id, d.month_start
    FROM your_table t
    CROSS JOIN target_dates d
)
-- 步骤3:查询每个组合对应的最新col2值
SELECT 
    aim.id,
    aim.month_start AS "col2(first day of every month)",
    -- 子查询:找到当前ID在month_start之前最新的修改记录
    (SELECT col2 
     FROM your_table t
     WHERE t.id = aim.id 
       AND t.modified <= aim.month_start
     ORDER BY t.modified DESC
     LIMIT 1) AS col4
FROM all_id_month aim
ORDER BY aim.id, aim.month_start;

代码解释

  • target_dates:用递归CTE生成你需要的4个月份的第一天,如果你需要扩展到更多月份,只需要修改WHERE条件里的日期即可。
  • all_id_month:通过CROSS JOIN把每个唯一ID和所有目标日期组合,保证不会漏掉任何ID的任何月份。
  • 子查询部分:对每个「ID+每月1日」,筛选出该日期之前的所有修改记录,按修改时间倒序排列后取第一条,就是我们要的最新值;如果没有符合条件的记录,子查询返回NULL,正好符合需求。

不同数据库的适配调整

如果你的数据库不是PostgreSQL,只需要调整日期生成和语法细节:

  • MySQL 8+:递归CTE支持,日期计算用DATE_ADD(month_start, INTERVAL 1 MONTH),子查询语法一致。
  • Oracle:用CONNECT BY生成日期,比如:
    SELECT ADD_MONTHS(DATE '2019-01-01', LEVEL-1) AS month_start
    FROM dual
    CONNECT BY LEVEL <=4
    
  • SQL Server:日期计算用DATEADD(month, 1, month_start),递归CTE语法类似。

验证结果

这个查询完全符合你给出的输出要求:

  • ID1的1月1日:没有早于2019-01-01的修改记录,返回NULL;
  • ID2的3月1日:3月2日的blue是在3月1日之后,所以取最近的1月12日的green;
  • ID3的1月1日:取2018年12月12日的red,以此类推。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:16:49