我有兩個表。 首先包含一些激活,其次包含一些停用。兩個表之間的增量項相關聯
我有一個去激活使用如下因素的規則只有一個激活相關聯:
- 激活必須先停用,但不會早於 92天。
- 與已經關聯的激活無法再次關聯 。
因此,使用一些數據:
--a activations, b - deactivations
create table a (id1 integer, date1 date);
create table b (id2 integer, date2 date);
insert into a values (1, '1-Feb-2013');
insert into a values (2, '2-Feb-2013');
insert into a values (3, '3-Feb-2013');
insert into a values (4, '1-Mar-2013');
insert into a values (5, '2-Mar-2013');
insert into a values (6, '1-May-2013');
insert into a values (7, '19-May-2013');
insert into b values (1, '1-May-2013');
insert into b values (2, '1-May-2013');
insert into b values (3, '15-May-2013');
insert into b values (4, '16-May-2013');
insert into b values (5, '17-May-2013');
insert into b values (6, '18-May-2013');
所需的輸出:
id1 date1 id2 date2
1 February, 01 2013 00:00:00+0000 1 May, 01 2013 00:00:00+0000 1 1
2 February, 02 2013 00:00:00+0000 2 May, 01 2013 00:00:00+0000 2 2
4 March, 01 2013 00:00:00+0000 3 May, 15 2013 00:00:00+0000 4 3
5 March, 02 2013 00:00:00+0000 4 May, 16 2013 00:00:00+0000 5 4
6 May, 01 2013 00:00:00+0000 5 May, 17 2013 00:00:00+0000 6 5
查詢產生的候選人將是:
select id1, date1, id2, date2
from a
join b
on a.date1 >= b.date2 - 91
and b.date2 >= a.date1;
我成功創建正確的查詢使用連接,但速度太慢(我有數以百萬計的客戶端每個客戶端都有數以千計的激活和停用設備。這個例子是一個客戶端。)
with chrn as
(
select id1, date1, id2, date2,
dense_rank() over ( order by date1, id1) as act_ord,
dense_rank() over (order by date2, id2) as deact_ord
from a
join b
on a.date1 >= b.date2 - 91
and b.date2 >= a.date1
)
select *
from (
select s.*, row_number() over (partition by lvl order by act_ord+deact_ord) as rnk
from (
select a1.*, level lvl
from chrn a1
connect by
prior deact_ord < deact_ord and
prior act_ord < act_ord and
(prior deact_ord = deact_ord - 1 or prior act_ord = act_ord - 1)
start with deact_ord = 1 and act_ord = 1
)s
)where rnk =1
;
我想找到這個一個更快的解決方案,也許只使用分析功能。由於候選和路徑的數量很大,遞歸查詢速度太慢。或者我沒有成功減少候選人和路徑的數量。
沒有ID必須與激活和失活的關係船什麼??? –
不,它只是我例子中的一行標識符。我有另一把鑰匙。 –
首先你不使用分區,請使用Rank而不是密集的排名,兩者都會給出相同的結果,但排名會有25%的好處。查看查詢進一步的變化,你試圖改變這個 –