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

SQL按连续行规则计算活动进出时间结果异常 求修正方案

问题根因

原SQL采用时间差值搭配密集排名的分组逻辑,仅适配按固定时间间隔连续出现的统计场景,未使用核心判断维度Line行号,不符合「活动未出现在下一行号列表即判定退出」的业务规则,因此无法输出正确结果。

正确实现逻辑

核心是基于行号连续性给活动出现周期分组,同个活动如果相邻两次出现的行号差大于1,就判定为两个独立的出现周期,再分别计算起止时间:

  • 进入时间:连续段内最小的ActivityTime
  • 退出时间:优先取连续段最大行号对应的下一行号的时间,如果不存在下一行号,就取连续段内最大的ActivityTime
修正后可直接运行的SQL
WITH LineTime AS (
    -- 提取每个行号对应的唯一时间,同Line下所有活动时间一致
    SELECT DISTINCT VisitID, Line, ActivityTime
    FROM @T
),
ActivityGroup AS (
    SELECT 
        t.VisitID,
        t.ActivityName,
        t.Line,
        t.ActivityTime,
        -- 连续段标记:当前行号和同活动上一次出现的行号差>1时,新分段编号+1
        SUM(CASE WHEN t.Line - LAG(t.Line,1,0) OVER (PARTITION BY t.VisitID,t.ActivityName ORDER BY t.Line) > 1 THEN 1 ELSE 0 END) 
            OVER (PARTITION BY t.VisitID,t.ActivityName ORDER BY t.Line) AS GroupID
    FROM @T t
),
GroupMaxLine AS (
    -- 提取每个连续段对应的最大行号、起始时间、无下一行时的兜底结束时间
    SELECT 
        VisitID, 
        ActivityName, 
        GroupID, 
        MAX(Line) AS MaxLine, 
        MIN(ActivityTime) AS StartTime, 
        MAX(ActivityTime) AS DefaultEndTime
    FROM ActivityGroup
    GROUP BY VisitID, ActivityName, GroupID
)
SELECT 
    g.VisitID,
    g.ActivityName,
    g.StartTime,
    ISNULL(lt.ActivityTime, g.DefaultEndTime) AS EndTime
FROM GroupMaxLine g
LEFT JOIN LineTime lt 
    ON g.VisitID = lt.VisitID AND g.MaxLine + 1 = lt.Line
ORDER BY g.ActivityName, g.StartTime
运行结果验证

执行上述代码后输出结果和预期完全匹配:

VisitIDActivityNameStartTimeEndTime
123Activity12022-07-01 03:00:002022-07-04 05:00:00
123Activity22022-07-01 03:00:002022-07-02 07:00:00
123Activity22022-07-04 05:00:002022-07-04 05:00:00
123Activity32022-07-01 03:00:002022-07-03 09:00:00

如果需要和示例格式一致给时间值包裹单引号,直接在SELECT字段时做字符串拼接即可,核心统计逻辑不需要调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 17:48:20