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

SQL分组过滤查询:筛选连接状态发生变更的Site_ID

需求背景

现有一张分钟级粒度记录站点连接状态的业务大表,总数据量数百万级,表结构如下:

TimestampSite_IDConnected_status
2022-05-14 00:00:00 UTC12345True
2022-05-14 00:01:00 UTC12345True
2022-05-14 00:02:00 UTC12345True
2022-05-14 00:03:00 UTC12345True
...(站点12345后续数千条记录)12345...
2022-05-14 00:00:00 UTC32145True
2022-05-14 00:01:00 UTC32145True
2022-05-14 00:02:00 UTC32145True
2022-05-14 00:03:00 UTC32145True
2022-05-14 00:04:00 UTC32145False
2022-05-14 00:05:00 UTC32145False
...(站点32145后续数千条记录)32145...

需要筛选出连接状态发生过变更(即同时存在True、False两种状态记录)的站点,输出格式为站点ID+固定值True代表存在状态变更。

最优SQL实现(适配百万级大表)

优先选择单次聚合的写法,执行效率最高,不需要额外的子查询、窗口函数计算,只要给Site_ID字段建好索引,百万级数据可以秒级返回结果:

SELECT
  Site_ID,
  TRUE AS Connected_status_change
FROM 你的业务表名 -- 替换成实际的表名
GROUP BY Site_ID
HAVING MIN(Connected_status) != MAX(Connected_status);

逻辑说明

  • Connected_status是布尔类型,只有True、False两个取值,布尔排序规则下False < True
  • 按Site_ID分组后,如果同一个站点下该字段的最小值和最大值不相等,就说明两种状态都存在,也就是发生过状态变更
  • 聚合计算时数据库只需要遍历一次数据,分组过程中直接记录每个分组的最值即可,不需要做去重、排序等额外操作,资源消耗最低

通用兼容写法

如果后续Connected_status可能新增其他状态值,也可以用去重计数的写法,逻辑是同一个站点下状态值种类数为2就代表发生过True/False的切换:

SELECT
  Site_ID,
  TRUE AS Connected_status_change
FROM 你的业务表名
GROUP BY Site_ID
HAVING COUNT(DISTINCT Connected_status) = 2;

注意:不要用多层EXISTS子查询、窗口函数逐行对比前后状态的写法,这类写法在大表场景下会生成大量临时计算结果,执行速度比上面的纯聚合写法慢3~10倍,很容易出现查询超时的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 21:51:27