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

按guid分组查询记录:指定日期取最大日期,无则取下一可用日最小记录

针对DATAS表的分组查询SQL实现

首先假设表结构如下(若实际结构有差异,可按需调整字段):

CREATE TABLE DATAS (
    guid VARCHAR(36) NOT NULL,
    startdate DATE NOT NULL,
    -- 其他业务字段示例
    col1 VARCHAR(50),
    col2 INT,
    PRIMARY KEY (guid, startdate) -- 假设组合主键,避免同guid同日期的重复记录
);

需求逻辑拆解

对每个guid,按以下规则筛选单条记录:

  1. 若存在startdate等于指定日期(假设参数为@target_date)的记录,取该日期下startdate最大的记录(因日期相同,实际为该日期的任意一条,若有重复可结合其他字段排序);
  2. 若指定日期无对应记录,取大于指定日期的最早可用日期中startdate最小的记录(即该最早日期的记录)。

最终SQL实现(支持窗口函数的数据库:MySQL 8.0+/PostgreSQL/SQL Server等)

WITH ranked_records AS (
    SELECT 
        *,
        -- 标记记录优先级:指定日期记录优先级最高,后续日期次之
        CASE 
            WHEN startdate = @target_date THEN 0
            WHEN startdate > @target_date THEN 1
            ELSE 2 -- 排除早于指定日期的非目标记录
        END AS priority,
        -- 按guid分组,按优先级+规则排序,生成唯一序号
        ROW_NUMBER() OVER (
            PARTITION BY guid 
            ORDER BY 
                priority,
                CASE WHEN startdate = @target_date THEN startdate END DESC,
                startdate ASC
        ) AS rn
    FROM DATAS
    WHERE startdate >= @target_date -- 仅保留符合规则的候选记录
)
SELECT guid, startdate, col1, col2 -- 替换为实际需要查询的字段
FROM ranked_records
WHERE rn = 1;

逻辑说明

  1. CTE子查询:
    • 通过CASE给记录划分优先级,指定日期的记录优先级为0,后续日期为1,早于指定日期的标记为2(后续过滤);
    • 使用ROW_NUMBER()按guid分组排序:先按优先级排序,同优先级内,指定日期组按startdate降序(兼容可能的时间精度差异),后续日期组按startdate升序(取最早的后续日期)。
  2. 主查询:筛选每个guid中序号为1的记录,即为符合需求的结果。

兼容无窗口函数的数据库(如MySQL 5.x)

SELECT d1.*
FROM DATAS d1
WHERE (d1.guid, d1.startdate) IN (
    SELECT 
        guid,
        CASE 
            -- 优先匹配指定日期
            WHEN EXISTS (SELECT 1 FROM DATAS d2 WHERE d2.guid = d.guid AND d2.startdate = @target_date)
            THEN @target_date
            -- 无匹配时取后续最早日期
            ELSE (SELECT MIN(startdate) FROM DATAS d3 WHERE d3.guid = d.guid AND d3.startdate > @target_date)
        END AS target_startdate
    FROM (SELECT DISTINCT guid FROM DATAS) d
)
-- 若同guid在目标日期有多条记录,取startdate最大的
AND d1.startdate = (
    SELECT MAX(startdate) FROM DATAS d4 WHERE d4.guid = d1.guid AND d4.startdate = d1.startdate
);

自定义调整提示

  • 若“指定日期存在对应记录”指startdate <= @target_date(而非严格等于),可将优先级0的条件改为startdate <= @target_date,并在排序时取该范围内最大的startdate;
  • 若表包含enddate(记录生效周期),需添加enddate >= @target_date的条件判断“指定日期是否有有效记录”,可根据业务场景调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:07:41