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记录。我当时认为用窗口函数可能有一种有效的方法可以做到这一点,但是没有太多的玩法。你会怎么写这个?
答案 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_id
,MATCH_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