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

如何查询连续3天及以上距离为0的人员及对应天数?

问题背景

现有数据表结构及数据如下:

DatePersonDistance
2022/01/01John15
2022/01/02John0
2022/01/03John0
2022/01/04John0
2022/01/05John19
2022/01/01Pete25
2022/01/02Pete12
2022/01/03Pete0
2022/01/04Pete0
2022/01/05Pete1
需求

找出所有连续3天及以上Distance为0的人员,并统计其最长连续天数。示例中预期结果如下:

PersonConsecutive Days with Zero
John3
用户尝试的SQL(存在问题)
Select Person, count(*), 
       (row_number() over (partition by Person, Date order by Person, Date))
from mytable
问题分析与正确解法

你写的SQL存在几个核心问题:

  1. 未筛选Distance = 0的记录,会把所有数据纳入计算,偏离需求
  2. 分区条件用Person, Date完全不合理——每个日期唯一,分区后每组仅一条数据,row_number()无法实现连续天数分组
  3. 缺乏连续日期的判断逻辑,单纯count(*)无法统计连续天数

要解决连续天数统计问题,核心思路是给每个连续的0距离日期组打标记,具体实现步骤如下:

  1. 先筛选出所有Distance = 0的记录
  2. 对每个人员按日期排序,通过日期与行号的差值识别连续日期组
  3. 按人员和连续组分组统计天数,最后筛选出天数≥3的记录

以下是适配多数SQL数据库(MySQL、PostgreSQL、SQL Server)的代码:

WITH zero_days AS (
    SELECT 
        Person,
        Date,
        -- 给每个人员的0距离日期按顺序编号
        ROW_NUMBER() OVER (PARTITION BY Person ORDER BY Date) AS rn
    FROM mytable
    WHERE Distance = 0
),
consecutive_groups AS (
    SELECT 
        Person,
        -- 通过日期减行号的固定偏移量,标记同一连续组
        DATE_SUB(Date, INTERVAL rn DAY) AS group_id -- MySQL写法
        -- PostgreSQL 替换为:(Date - INTERVAL '1 day' * rn) AS group_id
        -- SQL Server 替换为:DATEADD(day, -rn, Date) AS group_id
    FROM zero_days
),
group_counts AS (
    SELECT 
        Person,
        COUNT(*) AS consecutive_days
    FROM consecutive_groups
    GROUP BY Person, group_id
    HAVING COUNT(*) >= 3
)
SELECT 
    Person,
    MAX(consecutive_days) AS `Consecutive Days with Zero`
FROM group_counts
GROUP BY Person;

代码逻辑说明:

  • zero_days:筛选出所有距离为0的记录,给每个人员的日期按顺序编号
  • consecutive_groups:利用日期与行号的差值,将连续日期归为同一个group_id(连续日期的日期差与行号差相等,差值结果一致)
  • group_counts:按人员和分组统计连续天数,筛选出天数≥3的组
  • 最终取每个人员的最长连续天数,得到符合需求的结果

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 13:54:23