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

如何用SQL(含HANA SQLScript)查询覆盖指定日期区间的分组

解决方案:用递归CTE合并区间并验证覆盖

核心思路

先过滤掉与目标区间完全不重叠的无效条目,再通过递归CTE对每个分组的有效条目合并重叠/连续区间,最后验证合并后的区间是否能完全覆盖目标日期范围。该方法支持任意数量的分组条目,解决原LAG方案的局限性。

具体SQL实现(适配SAP HANA SQLScript/AMDP)

-- 定义目标区间变量,可根据需求修改
DECLARE @TARGET_FROM DATE = '2025-02-01';
DECLARE @TARGET_TO DATE = '2025-02-29'; -- 注意:2月无30号,此处修正为合法日期

WITH FilteredEntries AS (
    -- 第一步:筛选每个分组中与目标区间有交集的条目
    SELECT 
        group_id,
        valid_from,
        valid_to
    FROM your_table_name
    WHERE 
        valid_to >= @TARGET_FROM 
        AND valid_from <= @TARGET_TO
),
SortedEntries AS (
    -- 第二步:对每个分组的条目按valid_from排序,添加序号用于递归
    SELECT 
        group_id,
        valid_from,
        valid_to,
        ROW_NUMBER() OVER (PARTITION BY group_id ORDER BY valid_from) AS rn
    FROM FilteredEntries
),
MergedIntervals AS (
    -- 递归CTE的起始:每个分组的第一条条目
    SELECT 
        group_id,
        valid_from AS merged_from,
        valid_to AS merged_to,
        rn
    FROM SortedEntries
    WHERE rn = 1

    UNION ALL

    -- 递归逻辑:合并当前条目与上一个合并后的区间
    SELECT 
        se.group_id,
        -- 合并后的起始取较小值
        LEAST(se.valid_from, mi.merged_from),
        -- 合并后的结束取较大值(如果当前条目与上一个合并区间重叠/连续)
        CASE 
            WHEN se.valid_from <= mi.merged_to + INTERVAL '1' DAY THEN GREATEST(se.valid_to, mi.merged_to)
            ELSE se.valid_to
        END AS merged_to,
        se.rn
    FROM SortedEntries se
    INNER JOIN MergedIntervals mi 
        ON se.group_id = mi.group_id 
        AND se.rn = mi.rn + 1
),
FinalMerged AS (
    -- 每个分组保留最终合并后的最大覆盖区间(因为递归过程中会有中间结果,取每个分组的最后一条递归结果)
    SELECT 
        group_id,
        merged_from,
        merged_to
    FROM MergedIntervals mi
    WHERE rn = (SELECT MAX(rn) FROM MergedIntervals WHERE group_id = mi.group_id)
)
-- 第三步:筛选出能完全覆盖目标区间的分组
SELECT DISTINCT group_id
FROM FinalMerged
WHERE 
    merged_from <= @TARGET_FROM 
    AND merged_to >= @TARGET_TO;

代码说明

  • FilteredEntries:剔除完全在目标区间外的条目,减少后续计算量。
  • SortedEntries:对每个分组的有效条目按起始日期排序,生成序号用于递归遍历。
  • MergedIntervals:递归合并区间:
    • 初始层取每个分组的第一条条目作为初始合并区间。
    • 递归层将当前条目与上一个合并区间对比:如果当前条目的起始日期小于等于上一个合并区间的结束日期+1天(视为连续),则合并为一个更大的区间;否则保留为独立区间。
  • FinalMerged:提取每个分组最终的合并区间(递归的最后一条结果,即覆盖范围最大的合并区间)。
  • 最终查询:验证合并后的区间是否完全包含目标区间,输出符合条件的group_id。

注意事项

  • 若日期字段存储为字符串(如20250201),需先转换为DATE类型:TO_DATE(valid_from, 'YYYYMMDD')。
  • 若分组存在多个不连续但组合后能覆盖目标区间的条目(比如目标区间1-10,分组有1-5和6-10),代码会自动合并为连续区间并识别为符合条件。
  • 在AMDP中使用时,可将变量替换为AMDP的输入参数,或直接硬编码目标区间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 18:05:09