【问题标题】:Track state of time series event in SQL column在 SQL 列中跟踪时间序列事件的状态
【发布时间】:2021-07-11 00:57:00
【问题描述】:

这看起来很简单,但我无法弄清楚,在 SQL Server 中工作。我有时间序列数据,我想要一个列来跟踪每一行的 ON/OFF 事件的状态,所以当有一个 ON 事件时,Desired Output 列将为每个后续事件都有一个 1,直到有一个 OFF 事件。请看下面的例子。非常感谢!

TimeStamp Event Desired Output
1:01 ON 1
1:02 OFF 0
1:04 other 0
1:05 other 0
1:06 ON 1
1:10 other 1
1:12 other 1
1:14 OFF 0
1:15 other 0

【问题讨论】:

  • 根据问题指南,请展示您的尝试并告诉我们您发现了什么(在本网站或其他地方)以及为什么它不能满足您的需求。
  • 请阅读this,了解一些改进问题的技巧。 DDL 使我们免于猜测数据类型,例如为TimeStamp'ON''OFF' Event 是否可以重复,例如两个 'OFF' 事件没有干预 'ON'?
  • 感谢您的提示,很抱歉我还是 Stack Overflow 的新手。

标签: sql sql-server tsql time-series


【解决方案1】:

您可以比较ON和OFF的累积计数:

select t.*,
       (case when sum(case when event = 'ON' then 1 else 0 end) over (order by timestamp) >
                  sum(case when event = 'OFF' then 1 else 0 end)
             then 1 else 0
        end) as desired
from t;

【讨论】:

  • 戈登,非常感谢您的回复!这非常适合我提出的问题。但是,当我正在实施它时,我发现我没有考虑所有可能性,例如可能连续发生两个 ON 事件。我认为最终的解决方案实际上是使用 WHILE 循环进行迭代
  • @TrafficDataAnalyst 。 .我的建议是您接受这个问题的答案并提出一个新问题。
【解决方案2】:
WITH
  flagged AS
(
  SELECT
    timestamp,
    CASE WHEN event = 'ON'  THEN 1
         WHEN event = 'OFF' THEN 0 END   AS state
  FROM
    #table
),
  cumulative AS
(
  SELECT
    *,
    COUNT(state) OVER (ORDER BY timestamp)   AS state_group
  FROM
    flagged
)
SELECT
  timestamp,
  MAX(state) OVER (PARTITION BY state_group)   AS persisted_state
FROM
  cumulative

【讨论】:

  • 哇,这是 100% 的精彩!我在数据子集上尝试了我的循环方法,查询耗时 19 秒,而使用此方法只需 3 秒。效果很好,非常感谢!
  • @TrafficDataAnalyst - 你有时间戳索引吗?
  • 不,时间戳没有被索引。这是一个一次性用例,可能会在以后生产,因此性能目前并不重要,但可能会在以后。
  • 如果您好奇,我正在处理交通灯数据,其中 ON 和 OFF 是传感器检测车辆,我想知道传感器在绿灯期间开启了多长时间,如果传感器在灯变红后保持开启,因为这意味着不是每个人都能通过灯。
【解决方案3】:

我意识到实际上可能有两个 ON 事件连续发生,或者有时条目可能会丢失。所以为了跟踪这个事件的状态,我认为使用 WHILE 循环可能是最好的选择。

WHILE @CurrentRow <= @TotalRows
BEGIN
    SELECT @DesiredOutput = CASE WHEN Event = 'ON' THEN 1 ELSE CASE WHEN Event = 'OFF' THEN 0 ELSE @DesiredOutput END END
    FROM #Table
    WHERE @CurrentRow = Row_Number

    UPDATE #Table
    SET DesiredOutput = @DesiredOutput
    WHERE @CurrentRow = Row_Number
    
    SET @CurrentRow += 1
END

【讨论】:

  • 循环不好,嗯。我会为你添加一个基于集合的答案,但我正在使用手机,请给我“片刻”。
猜你喜欢
  • 1970-01-01
  • 2017-10-17
  • 2010-11-09
  • 1970-01-01
  • 1970-01-01
  • 2016-04-09
  • 2011-11-14
  • 2016-05-11
  • 1970-01-01
相关资源
最近更新 更多