计算值是否连续

时间:2018-08-24 08:02:27

标签: sql postgresql-10

这是我的桌子:

Event       Order               Timestamp
delFailed   281475031393706     2018-07-24T15:48:08.000Z
reopen      281475031393706     2018-07-24T15:54:36.000Z
reopen      281475031393706     2018-07-24T15:54:51.000Z

我需要计算事件'delFailed'和'reopen'的数量以计算#delFailed - #reopen。 困难在于不能有两个相同的连续事件,因此在这种情况下结果将是“ 0”而不是“ -1”。

这是我到目前为止所取得的成就(这是错误的,因为由于有两个连续的“重新打开”事件,它给了我-1而不是0)

with 
    events as (
        select 
            event as events,
            orders,
            "timestamp"
        from main_source_execevent
        where orders = '281475031393706'
        and event in ('reopen', 'delFailed')
        order by "timestamp"
    ),
    count_events as (
        select 
            count(events) as CEvents,
            events,
            orders
        from events
        group by orders, events
    )
select (
    (select cevents from count_events where events = 'delFailed') - (select cevents from count_events where events = 'reopen')
) as nAttempts,
orders
from count_events
group by orders

如果有两个相同的连续事件,我怎么计数一次?

2 个答案:

答案 0 :(得分:1)

这是一个空白问题,您可以使用make来行号来检查行是否是两个相同的连续事件

说明

  1. 正常创建的一个行号。
  2. Event列创建的另一个行号

SELECT *
  FROM (
    SELECT *
          ,ROW_NUMBER() OVER(ORDER BY Timestamp) grp
          ,ROW_NUMBER() OVER(PARTITION BY Event ORDER BY Timestamp) rn
    FROM T
  ) t1


|     event |           Order |            timestamp | grp | rn |
|-----------|-----------------|----------------------|-----|----|
| delFailed | 281475031393706 | 2018-07-24T15:48:08Z |   1 |  1 |
|    reopen | 281475031393706 | 2018-07-24T15:54:36Z |   2 |  1 |
|    reopen | 281475031393706 | 2018-07-24T15:54:51Z |   3 |  2 |

在创建这两行时,您可以获得较高的结果,然后使用grp - rn来计算该行连续还是不连续。

 SELECT *,grp-rn
  FROM (
    SELECT *
          ,ROW_NUMBER() OVER(ORDER BY Timestamp) grp
          ,ROW_NUMBER() OVER(PARTITION BY Event ORDER BY Timestamp) rn
    FROM T
  ) t1

|     event |           Order |            timestamp | grp | rn |   grp-rn |
|-----------|-----------------|----------------------|-----|----|----------|
| delFailed | 281475031393706 | 2018-07-24T15:48:08Z |   1 |  1 |        0 |
|    reopen | 281475031393706 | 2018-07-24T15:54:36Z |   2 |  1 |        1 |
|    reopen | 281475031393706 | 2018-07-24T15:54:51Z |   3 |  2 |        1 |

您可以看到grp-rn列中是否有两个相同的连续事件,因此我们可以按group bygrp-rn来获取count

最终查询。

CREATE TABLE T(
  Event VARCHAR(50),
  "Order"  VARCHAR(50),
  Timestamp Timestamp
); 

INSERT INTO T VALUES ('delFailed',281475031393706,'2018-07-24T15:48:08.000Z');
INSERT INTO T VALUES ('reopen',281475031393706,'2018-07-24T15:54:36.000Z');
INSERT INTO T VALUES ('reopen',281475031393706,'2018-07-24T15:54:51.000Z');

查询1

SELECT 
    SUM(CASE WHEN  event = 'delFailed' THEN 1 END) -  
    SUM(CASE WHEN  event = 'reopen' THEN 1 END) result
FROM (
  SELECT Event,COUNT(distinct Event)
  FROM (
    SELECT *
          ,ROW_NUMBER() OVER(ORDER BY Timestamp) grp
          ,ROW_NUMBER() OVER(PARTITION BY Event ORDER BY Timestamp) rn
    FROM T
  ) t1
  group by grp - rn,Event
)t1

Results

| result |
|--------|
|      0 |

答案 1 :(得分:1)

我只会使用lag()来获取任何相似值序列中的第一个事件。然后进行计算:

select sum( (event = 'reopen')::int ) as num_reopens,
       sum( (event = 'delFailed')::int ) as num_delFailed
from (select mse.*,
             lag(event) over (partition by orders order by "timestamp") as prev_event
      from main_source_execevent mse
      where orders = '281475031393706' and
            event in ('reopen', 'delFailed')
     ) e
where prev_event <> event or prev_event is null;