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

SQL Server 2005:如何排除字段存在连续重复值的行

解决连续重复状态码的保留问题

这个问题属于SQL里经典的连续相同值分组(岛屿问题),你踩的坑太常见了——普通的GROUP BY或者仅按status_code分区的ROW_NUMBER()函数,只会根据值本身分组,完全不关注行的顺序和连续的上下文,自然会把所有状态为"B"的记录归为一组,而忽略了它们是两次独立的状态变更(非"B"→"B")。

核心思路:标记连续相同状态的分组

我们需要先给每一段连续相同的状态码打上唯一的分组ID,这样哪怕状态码相同,只要中间有其他状态隔开,就会被分到不同的组里。具体步骤如下:

  • 使用LAG()窗口函数获取当前行的上一行状态码,对比当前行的状态码——如果不同,说明是新的状态组的开始,标记为1;如果相同,标记为0。
  • 对这个标记值做累加(SUM() OVER (ORDER BY record_date)),这样每一段连续相同的状态码会得到一个唯一的group_id。
  • 最后按group_id和status_code分组,取每个组里最早的日期(状态变更的起始日期)即可。

完整SQL示例

假设你的源表名为status_log,包含record_date(日期字段)和status_code(状态码字段),可以用以下查询实现需求:

WITH status_groups AS (
    SELECT 
        record_date,
        status_code,
        -- 标记状态变更的起始行,累加得到分组ID
        SUM(
            CASE 
                WHEN status_code = LAG(status_code) OVER (ORDER BY record_date) THEN 0 
                ELSE 1 
            END
        ) OVER (ORDER BY record_date) AS group_id
    FROM status_log
)
SELECT 
    MIN(record_date) AS change_date,  -- 保留状态变更的最早日期
    status_code
FROM status_groups
GROUP BY group_id, status_code
ORDER BY change_date;

代码解释

  • LAG(status_code) OVER (ORDER BY record_date):按日期排序后,获取当前行的上一行状态码,用来判断是否发生了状态变更。
  • SUM(...) OVER (ORDER BY record_date):累加状态变更标记,生成的group_id会把每一段连续相同的状态码归为一组——比如第一次从非"B"变"B"的所有连续行是group_id=2,第二次变"B"的连续行是group_id=4(假设中间有其他状态)。
  • 最后分组取MIN(record_date),就是每个状态组的起始日期,也就是你需要保留的状态变更行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:20:40