Oracle窗口函数

时间:2017-05-06 16:45:06

标签: sql oracle

CREATED_DATE | ENTITY_ID | TYPE
02-MAY-17 | 1234 | A 
03-MAY-17 | 1234 | B
04-MAY-17 | 1234 | B
05-MAY-17 | 1234 | B

我试图写一个将返回的查询:

ENTITY_ID | DIFF_BETWEEN_A_B1 | DIFF_BETWEEN_A_B2
1234 | 1 | 2
...

我尝试编写一个查询,显示获取第一个TYPE A记录和第一个TYPE B记录之间的时间,以及每个ENTITY_ID的第一个TYPE A记录和第二个TYPE B记录。将有超过2个B类记录但只有一个TYPE A记录。我当时认为用窗口函数可能有一种有效的方法可以做到这一点,但是没有太多的玩法。你会怎么写这个?

2 个答案:

答案 0 :(得分:2)

这是一种使用条件聚合的方法:

select t.entity_id,
       max(case when seqnum = 1 and type = 'B' then created_date end) 
        - max(a_created_date) as diff_1,
       max(case when seqnum = 2 and type = 'B' then created_date end) 
        - max(a_created_date) as diff_2
from (select t.*,
             min(case when type = 'A' then created_date end) over (partition by entity_id) as a_created_date,
             row_number() over (partition by entity_id, type order by created_date) as seqnum
      from t
      where type in ('A', 'B')
     ) t
group by entity_id;

答案 1 :(得分:1)

以下是在Oracle 12.1及更高版本中执行此操作的方法。

由于每个type = 'A'只有一行entity_idMATCH_RECOGNIZE中的排序保证了我们计算所需的行将是每个分区中的前三行。这意味着不需要DEFINE子句;但语法要求它(这就是为什么它只是要求0 = 0)。

with
     test_data ( created_date, entity_id, tp ) as (
       select to_date('02-MAY-17', 'dd-MON-rr'), 1234, 'A' from dual union all 
       select to_date('03-MAY-17', 'dd-MON-rr'), 1234, 'B' from dual union all
       select to_date('04-MAY-17', 'dd-MON-rr'), 1234, 'B' from dual union all
       select to_date('05-MAY-17', 'dd-MON-rr'), 1234, 'B' from dual
     )
-- End of test data (not part of the solution). SQL query begins below this line
select entity_id, diff_between_a_b1, diff_between_a_b2
from   test_data
match_recognize (
  partition by entity_id
  order by     tp, created_date
  measures     b1.created_date - a.created_date as diff_between_a_b1,
               b2.created_date - a.created_date as diff_between_a_b2  
  pattern      ( ^ a b1 b2 )
  define       a as 0 = 0
)
;

ENTITY_ID  DIFF_BETWEEN_A_B1  DIFF_BETWEEN_A_B2
---------  -----------------  -----------------
     1234                  1                  2