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

SQL按Sl.No分组选取距基准日期最近日期行的实现方法

按Sl.No分组取日期匹配行SQL方案

核心逻辑

基准日期固定为2022-06-17(原格式6/17/2022),按Sl.No分组后选行规则:

  • 组内所有日期均晚于基准日(全未来):取距离基准日最近的最早未来日期对应行
  • 组内所有日期均早于/等于基准日(全过去):取距离基准日最近的最晚过去日期对应行
    涉及表字段:Sl.No、Date、status、flag

支持窗口函数的数据库写法(MySQL8.0+/PostgreSQL/SQL Server/Oracle12c+)

用窗口函数一次排序取每组第一行,逻辑清晰性能好:

WITH date_calc AS (
    SELECT
        *,
        ABS(DATEDIFF(`Date`, '2022-06-17')) AS diff_day,
        `Date` > '2022-06-17' AS is_future
    FROM -- 替换下面的表名为你的实际表名
        your_biz_table
)
SELECT Sl.No, Date, status, flag
FROM (
    SELECT
        *,
        ROW_NUMBER() OVER (
            PARTITION BY Sl.No
            ORDER BY
                is_future DESC, -- 组内同时有过去/未来时优先选未来日期,覆盖边界场景
                diff_day ASC, -- 优先选和基准日间隔最小的日期
                `Date` ASC -- 同间隔时未来选最早、过去选最晚,匹配规则要求
        ) AS rn
    FROM date_calc
) res
WHERE rn = 1;

低版本兼容写法(不支持窗口函数场景,如MySQL5.x)

通过分组聚合算出每组目标日期,再关联原表取完整行:

SELECT t1.*
FROM your_biz_table t1
JOIN (
    SELECT
        Sl.No,
        MIN(CASE WHEN `Date` > '2022-06-17' THEN `Date` END) AS nearest_future,
        MAX(CASE WHEN `Date` <= '2022-06-17' THEN `Date` END) AS nearest_past
    FROM your_biz_table
    GROUP BY Sl.No
) t2 ON t1.Sl.No = t2.Sl.No
WHERE
    (t2.nearest_future IS NOT NULL AND t1.Date = t2.nearest_future)
    OR (t2.nearest_future IS NULL AND t1.Date = t2.nearest_past);

使用注意

  • 所有your_biz_table占位符替换为实际业务表名
  • 日期函数适配对应数据库:SQL Server的DATEDIFF需调整参数顺序为DATEDIFF(day, '2022-06-17', [Date]),Oracle计算天数差直接用ABS("Date" - DATE '2022-06-17')即可
  • 如果Date字段存为字符串,先转成日期类型再计算,避免字符串排序导致结果错误

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 09:33:38