PLSQL-满足条件时测量持续时间

发布于 2024-10-25 13:20:25 字数 478 浏览 1 评论 0原文

假设如下表所示:

time    name availability
10:00   A   100
10:05   A   0
10:10   A   0
10:15   A   0
10:20   A   0
10:25   A   0
10:30   A   100
10:35   A   0
10:40   A   0
10:45   A   100
10:50   A   100
10:55   A   0
11:00   A   100
11:05    A   0

我想计算可用性等于零的每个事件的持续时间,这不仅意味着“0”的计数,还意味着下一个值再次变为之前第一个零和最后一个零之间的持续时间是多少100.

例如,在我的表中,我有 3 对事件 (up=100,down=0,up),其中第一个持续 25 分钟 (10:05-10:25),第二个持续 10 分钟,第三个持续 5 分钟。最后一个零不是 up-down-up 事件的一部分!

Assume a table as shown below:

time    name availability
10:00   A   100
10:05   A   0
10:10   A   0
10:15   A   0
10:20   A   0
10:25   A   0
10:30   A   100
10:35   A   0
10:40   A   0
10:45   A   100
10:50   A   100
10:55   A   0
11:00   A   100
11:05    A   0

I want to calculate the duration of each event where the availability equals zero, meaning not just the count of "0" BUT what was the duration between the first zero and the last zero before the next value becomes again 100.

For example, in my table, I have 3 pair events (up=100,down=0,up) where the first lasts 25min (10:05-10:25), the second 10min and the third 5min. The last zero is not part of an up-down-up event!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟若柳尘 2024-11-01 13:20:31

LAG功能可以帮助您:
Oracle LAG 函数

The LAG function can help you:
Oracle LAG function

转角预定愛 2024-11-01 13:20:30

这并不能用原始之美来回答,至少据我所知。

不过,实现起来并不难。不过,您必须与分析函数成为朋友。在这种情况下:滞后和超前。

如果这是您想要得到的(我确信您可以自己计算差异,有趣的部分是获取范围),然后查看下面的查询:

10:00   A   100     
10:05   A   0   10:05   10:25
10:10   A   0   10:05   10:25
10:15   A   0   10:05   10:25
10:20   A   0   10:05   10:25
10:25   A   0   10:05   10:25
10:30   A   100     
10:35   A   0   10:35   10:40
10:40   A   0   10:35   10:40
10:45   A   100     
10:50   A   100     
10:55   A   0   10:55   10:55
11:00   A   100     
11:05   A   0   11:05   11:05

with startTime as
(
  SELECT time
        ,Name
        ,case
           when t.availability = 0 and
           /* see the default value passed to "lag", 
              if nothing gets returned (first row), we return 2 which is > 0 */
                 lag(availability, 1,2) OVER(partition BY Name ORDER BY time) > 0 then 
            time
         end start_time
  FROM   SampleTable t
)
,stopTime as
(
  SELECT time
        ,name
        ,case
           when t.availability = 0 and
           /* see the default value passed to "lead" 
              if nothing gets returned (last row), we return 2 which is > 0*/
                (lead(availability, 1, 2) OVER(partition BY Name ORDER BY time) > 0) then
            time
         end stop_time
  FROM   SampleTable t
)
SELECT t.time
      ,t.Name
      ,t.availability
      ,case
         when t.availability = 0 then
          (SELECT Max(start_time)
           FROM   startTime
           WHERE  start_time is not null
           and    time <= t.time)
       end as start_time
      ,case
         when t.availability = 0 then
          (SELECT Min(stop_time)
           FROM   stopTime
           WHERE  stop_time is not null
           and    time >= t.time)
       end as stop_time
FROM   SampleTable t
ORDER  BY t.time

This isn't going to be answered with something of pristine beauty, at least not to my knowledge.

It isn't that hard to accomplish, though. You have to become friends with analytic functions, though. in this case: Lag and Lead.

If this is what you want to get (I am positive you can calculate the difference yourself, the interesting part is to get the ranges), then check out the query below:

10:00   A   100     
10:05   A   0   10:05   10:25
10:10   A   0   10:05   10:25
10:15   A   0   10:05   10:25
10:20   A   0   10:05   10:25
10:25   A   0   10:05   10:25
10:30   A   100     
10:35   A   0   10:35   10:40
10:40   A   0   10:35   10:40
10:45   A   100     
10:50   A   100     
10:55   A   0   10:55   10:55
11:00   A   100     
11:05   A   0   11:05   11:05

with startTime as
(
  SELECT time
        ,Name
        ,case
           when t.availability = 0 and
           /* see the default value passed to "lag", 
              if nothing gets returned (first row), we return 2 which is > 0 */
                 lag(availability, 1,2) OVER(partition BY Name ORDER BY time) > 0 then 
            time
         end start_time
  FROM   SampleTable t
)
,stopTime as
(
  SELECT time
        ,name
        ,case
           when t.availability = 0 and
           /* see the default value passed to "lead" 
              if nothing gets returned (last row), we return 2 which is > 0*/
                (lead(availability, 1, 2) OVER(partition BY Name ORDER BY time) > 0) then
            time
         end stop_time
  FROM   SampleTable t
)
SELECT t.time
      ,t.Name
      ,t.availability
      ,case
         when t.availability = 0 then
          (SELECT Max(start_time)
           FROM   startTime
           WHERE  start_time is not null
           and    time <= t.time)
       end as start_time
      ,case
         when t.availability = 0 then
          (SELECT Min(stop_time)
           FROM   stopTime
           WHERE  stop_time is not null
           and    time >= t.time)
       end as stop_time
FROM   SampleTable t
ORDER  BY t.time
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文