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

基于Grafana+PostgreSQL的时序数据时长条件可视化需求

解决PostgreSQL时序数据中筛选合格时段并生成标记列的方案

针对你的需求,我们可以通过PostgreSQL的窗口函数解决这类连续时序分组(岛屿问题),最终生成用于Grafana展示的0/1标记列。假设你的数据表名为time_series_data,包含字段timestamp(时间戳)、x、y,以下是分步实现方案:

核心思路

  1. 先标记每行是否满足x=0且y=1的基础条件
  2. 用窗口函数给连续满足基础条件的行分配同一个组ID(即"岛屿")
  3. 计算每个组的持续时长,判断是否≥3分钟
  4. 关联回原数据,给符合总时长要求的时段标记1,其余标记0

完整SQL代码

WITH qualified_rows AS (
  -- 第一步:标记每行是否满足基础条件
  SELECT
    timestamp,
    x,
    y,
    CASE WHEN x = 0 AND y = 1 THEN 1 ELSE 0 END AS is_qualified
  FROM time_series_data
),
grouped_islands AS (
  -- 第二步:给连续满足条件的行分配组ID
  SELECT
    *,
    -- 累加前面不满足条件的行数,连续合格行的组ID会保持一致
    SUM(1 - is_qualified) OVER (ORDER BY timestamp) AS island_id
  FROM qualified_rows
),
island_durations AS (
  -- 第三步:计算每个组的时间范围和持续时长(转成分钟)
  SELECT
    island_id,
    MIN(timestamp) AS start_time,
    MAX(timestamp) AS end_time,
    EXTRACT(EPOCH FROM (MAX(timestamp) - MIN(timestamp))) / 60 AS duration_minutes
  FROM grouped_islands
  GROUP BY island_id
)
-- 第四步:生成最终的展示标记列
SELECT
  gr.timestamp,
  gr.x,
  gr.y,
  CASE
    WHEN gr.is_qualified = 0 THEN 0  -- 不满足基础条件的行直接标记0
    WHEN id.duration_minutes >= 3 THEN 1  -- 合格且持续≥3分钟标记1
    ELSE 0  -- 合格但时长不足标记0
  END AS display_flag
FROM grouped_islands gr
JOIN island_durations id ON gr.island_id = id.island_id
ORDER BY gr.timestamp;

关键细节说明

  • 组ID生成逻辑:SUM(1 - is_qualified) OVER (ORDER BY timestamp)会在每次遇到不满足条件的行时累加数值,这样连续满足条件的行就会被分到同一个组里,完美解决行间隔不固定的问题。
  • 时长计算:用EXTRACT(EPOCH FROM ...)将时间差转成秒,再除以60得到分钟数,方便判断是否≥3分钟。
  • 适配多维度场景:如果你的数据是按设备/分区划分的,只需在窗口函数和GROUP BY中加上PARTITION BY 设备ID,比如SUM(1 - is_qualified) OVER (PARTITION BY device_id ORDER BY timestamp),确保每个设备单独计算合格时段。

Grafana可视化配置

将上述SQL作为数据源查询,在Grafana中:

  1. 选择timestamp作为时间字段
  2. 选择display_flag作为值字段
  3. 配置时序图表即可展示符合要求的时段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:43:20