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

SQL如何根据字段值变化计数 连续同值区间显示相同count值

实现逻辑

这个需求属于SQL经典的连续区间分组(岛屿问题)场景,核心计数逻辑分三步:

  • 按Date字段升序排列所有记录,取每一行上一条记录的test字段值
  • 逐行对比当前行test值和上一行值:值相同标记为0,值不同(包括第一行无前序记录的场景)标记为1
  • 对标记值做从第一行到当前行的累计求和,得到的结果就是需要的count字段值,相同连续值的记录会被分到同一个count编号下。
标准SQL写法(支持窗口函数的数据库)

MySQL 8.0+、PostgreSQL、SQL Server、Oracle 等主流数据库新版本都支持窗口函数,直接用下面的写法即可,把CTE里的测试表替换成你自己的真实表名就能运行:

WITH your_table AS (
    -- 以下是你提供的测试数据,实际使用时删除该CTE,直接查询你的业务表即可
    SELECT 1 AS Date, 'Yes' AS test UNION ALL
    SELECT 2 AS Date, 'Yes' AS test UNION ALL
    SELECT 3 AS Date, 'No' AS test UNION ALL
    SELECT 4 AS Date, 'Yes' AS test UNION ALL
    SELECT 5 AS Date, 'Yes' AS test UNION ALL
    SELECT 6 AS Date, 'No' AS test
)
SELECT 
    Date,
    test,
    SUM(change_flag) OVER (ORDER BY Date ROWS UNBOUNDED PRECEDING) AS count
FROM (
    SELECT
        Date,
        test,
        CASE WHEN LAG(test) OVER (ORDER BY Date) = test THEN 0 ELSE 1 END AS change_flag
    FROM your_table
) t
ORDER BY Date;

执行后返回的结果完全匹配你的预期:

Datetestcount
1Yes1
2Yes1
3No2
4Yes3
5Yes3
6No4
低版本MySQL兼容写法(5.x版本,不支持窗口函数)

如果使用不支持窗口函数的老版本MySQL,可以用用户变量实现相同逻辑:

SELECT
    Date,
    test,
    @group_count := IF(@last_test = test, @group_count, @group_count + 1) AS count,
    @last_test := test
FROM
    your_table,
    (SELECT @group_count := 0, @last_test := NULL) AS var_init
ORDER BY Date ASC;
注意事项
  • 必须保证排序字段能唯一确定行的顺序,你当前场景用Date排序符合要求,如果存在相同Date的多条记录,需要补充其他排序字段,避免分组逻辑混乱
  • 如果你的数据库把count作为保留字运行报错,可以换个别名比如group_id避免语法冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 08:31:09