如何从Oracle表中选择行组?

时间:2015-04-29 09:42:55

标签: oracle plsql

我在Oracle表中有三百万个数据,分为三列,即时间戳,状态和值。

从temp_table rownum<中选择Rownum,Timestamp,Status,OrderId 11; 返回

1 2015-04-28T12:41:34.1616834Z预订100
2 2015-04-28T12:41:34.1888649Z删除100
3 2015-04-28T12:55:59.3789387Z执行200
4 2015-04-28T12:55:59.3825833Z坚持200
5 2015-04-28T12:55:59.3898336Z书200
6 2015-04-28T12:55:59.3903645Z删除200

7 2015-04-28T12:57:37.5718992Z预订200
8 2015-04-28T12:57:37.5723847Z删除200
9 2015-04-28T12:57:37.5725199Z预订300
10 2015-04-28T12:57:37.5728888Z删除300

我感兴趣的是对于那天的每个orderId,按执行,持久,预订和删除分组的四个时间戳列表。

我对第7行和第8行不感兴趣,即使orderId相同[因为它们没有按执行,持久,预订和删除的方式组合在一起]。

我可以通过分析函数来完成吗?

由于

1 个答案:

答案 0 :(得分:0)

不是很优雅,但是工作查询:

with t1 as (
  select tstamp ts, status st, orderid oid, 
      decode(status, 'Execute', 1, 'Persist', 2, 'Book', 3, 'Delete', 4, 5) ds
    from temp_table),
t2 as (
  select ts, st, oid, ds
    , decode(ds, 1, 1, lag(ds, ds-1) 
        over (partition by oid, trunc(ts) order by ts, ds)) d1
    , case when ds = 1 then lead(ds) over (partition by oid, trunc(ts) order by ts, ds)
           when ds = 2 then 2
           when ds = 3 then lag(ds) over (partition by oid, trunc(ts) order by ts, ds)
           when ds = 4 then lag(ds, 2) over (partition by oid, trunc(ts) order by ts, ds)
      end d2
    , case when ds = 1 then lead(ds, 2) over (partition by oid, trunc(ts) order by ts, ds)
           when ds = 2 then lead(ds) over (partition by oid, trunc(ts) order by ts, ds)
           when ds = 3 then 3
           when ds = 4 then lag(ds) over (partition by oid, trunc(ts) order by ts, ds)
      end d3
    , decode(ds, 4, 4, lead(ds, 4-ds) 
        over (partition by oid, trunc(ts) order by ts, ds)) d4
  from t1 )
select ts, st, oid from t2
  where (d1, d2, d3, d4) in ((1, 2, 3, 4))
  order by oid, ts, ds