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

寻求SQL查询语句以获取备用电源的启停时间

备用电源启停时间SQL查询方案

需求说明

需要编写SQL查询语句,从发电机电表数据中提取备用电源的启动和停止时间。

发电机电表数据

SnoTIMESTAMPVALUE
12023-08-22 19:56:00.01010837
22023-08-22 19:57:00.01310837
32023-08-22 19:58:00.01010837
42023-08-22 19:59:00.12310840
52023-08-22 20:00:00.34710840
62023-08-22 20:01:00.56310841
72023-08-22 20:02:00.95310842
82023-08-22 20:03:00.00710842
92023-08-22 20:04:00.00310843
102023-08-22 20:05:00.01710843
112023-08-22 20:06:00.00710844
122023-08-22 20:07:00.00010844
132023-08-22 20:08:00.01710845
142023-08-22 20:09:00.00310845
152023-08-22 20:10:00.03010846
162023-08-22 20:11:00.01710846
172023-08-22 20:12:00.01310847
222023-08-22 20:13:00.02010848
232023-08-22 20:14:00.01010848
242023-08-22 20:15:00.01310849
252023-08-22 20:16:00.09310849
262023-08-22 20:17:00.29710849
272023-08-22 20:18:00.55710849
282023-08-23 21:22:00.82310849
292023-08-23 21:23:00.82310850
302023-08-23 21:24:00.82310851
312023-08-23 21:25:00.82310852
322023-08-23 21:26:00.82310853
332023-08-23 21:27:00.82310854
342023-08-23 21:28:00.82310854
352023-08-23 21:29:00.82310855
362023-08-23 21:30:00.82310855
372023-08-23 21:31:00.82310855
382023-08-23 21:32:00.82310855
392023-08-23 21:33:00.82310855
402023-08-23 21:34:00.82310855

判定规则

  • 启动时间:当VALUE值与上一行相比发生变化时,当前行的TIMESTAMP即为备用电源的启动时间(例如数据中VALUE从10837变为10840的时刻)。
  • 停止时间:当VALUE值停止变化,且后续连续10行或10分钟内VALUE均无变化时,最后一次VALUE变化对应的TIMESTAMP即为停止时间。

数据示例说明

  • 首次启动时间为第4行的2023-08-22 19:59:00.123,停止时间为第24行的2023-08-22 20:15:00.013(后续3个值均无变化)。
  • 第二次启动时间为第29行的2023-08-23 21:23:00.823,停止时间为第35行的2023-08-23 21:29:00.823。

期望查询结果

snostart date timestop date time
12023-08-22 19:59:00.1232023-08-22 20:15:00.013
22023-08-23 21:23:00.8232023-08-23 21:29:00.823

SQL查询语句

以下是基于窗口函数实现的查询方案,适用于支持LAG()、LEAD()和窗口函数的SQL数据库(如MySQL 8.0+、PostgreSQL、SQL Server等):

WITH change_events AS (
    -- 标记VALUE发生变化的行,以及后续是否满足停止条件
    SELECT
        Sno,
        TIMESTAMP,
        VALUE,
        -- 标记当前行是否是启动事件(VALUE与上一行不同)
        CASE WHEN VALUE != LAG(VALUE) OVER (ORDER BY TIMESTAMP) THEN 1 ELSE 0 END AS is_start,
        -- 检查后续10行内是否有VALUE变化,或后续10分钟内是否有变化
        CASE WHEN EXISTS (
            SELECT 1 
            FROM generator_meter t2
            WHERE t2.TIMESTAMP > t1.TIMESTAMP
              AND t2.TIMESTAMP <= DATE_ADD(t1.TIMESTAMP, INTERVAL 10 MINUTE)
              AND t2.VALUE != t1.VALUE
        ) OR EXISTS (
            SELECT 1 
            FROM generator_meter t2
            WHERE t2.Sno > t1.Sno
              AND t2.Sno <= t1.Sno + 10
              AND t2.VALUE != t1.VALUE
        ) THEN 0 ELSE 1 END AS is_stop_candidate
    FROM generator_meter t1
),
start_stop_groups AS (
    -- 分组识别每个启停周期
    SELECT
        *,
        SUM(is_start) OVER (ORDER BY TIMESTAMP) AS group_id
    FROM change_events
    WHERE is_start = 1 OR is_stop_candidate = 1
)
-- 提取每个组的启动和停止时间
SELECT
    ROW_NUMBER() OVER (ORDER BY MIN(TIMESTAMP)) AS sno,
    MIN(CASE WHEN is_start = 1 THEN TIMESTAMP END) AS `start date time`,
    MAX(CASE WHEN is_stop_candidate = 1 THEN TIMESTAMP END) AS `stop date time`
FROM start_stop_groups
GROUP BY group_id
HAVING `start date time` IS NOT NULL AND `stop date time` IS NOT NULL;

语句说明

  1. change_events CTE:
    • 使用LAG()函数比较当前行与上一行的VALUE,标记启动事件。
    • 通过子查询检查当前行后续10分钟或10行内是否有VALUE变化,标记潜在的停止候选行。
  2. start_stop_groups CTE:
    • 对启动事件进行累加,生成每个启停周期的分组ID,将同一周期的启动和停止行归为一组。
  3. 最终查询:
    • 按分组ID聚合,提取每组的启动时间(最早的启动事件)和停止时间(最晚的停止候选行),并生成结果序号。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 14:20:54