2017-04-19 4 views
1

Hintergrund: Ich habe Bereiche, die oft aktualisiert werden, um Preise für verschiedene Mengen von Materialien festzulegen. Sobald bestimmte Quoten erfüllt sind, werden die Preise fallen gelassen. Das Problem besteht darin, die aktuellen Preise zu identifizieren, nachdem Bereiche aktualisiert oder hinzugefügt wurden.Filtern zu nicht überlappenden Bereichen - Amazon RedShift

Ich suche nicht kontinuierliche Bereiche aus einem Datensatz herauszufiltern. Hier finden Sie einige Testcode:

drop table if exists public.test_ranges; 
create table public.test_ranges (
    category  integer 
    ,lower_bound integer 
    ,upper_bound integer 
    ,cost   numeric(10,2) 
    ,modifieddate timestamp 
); 

insert into public.test_ranges values (1,0,70456,0,'2015-09-29'); 
insert into public.test_ranges values (1,53956,60000,1.28,'2015-02-11'); 
insert into public.test_ranges values (1,70456,90000,1.02,'2015-09-29'); 
insert into public.test_ranges values (1,90000,120000,0.88,'2015-02-11'); 
insert into public.test_ranges values (1,120000,999999999,0.79,'2015-02-11'); 

insert into public.test_ranges values (2,0,48786,0,'2015-11-02'); 
insert into public.test_ranges values (2,22500,25000,0.43,'2015-02-17'); 
insert into public.test_ranges values (2,48786,50000,0.37,'2015-11-02'); 
insert into public.test_ranges values (2,50000,100000,0.21,'2015-02-17'); 
insert into public.test_ranges values (2,100000,175000,0.19,'2015-02-17'); 
insert into public.test_ranges values (2,175000,999999999,0.17,'2015-02-17'); 

insert into public.test_ranges values (3,0,585969,0,'2015-11-02'); 
insert into public.test_ranges values (3,346667,375000,0.15,'2014-09-12'); 
insert into public.test_ranges values (3,375000,500000,0.14,'2014-09-12'); 
insert into public.test_ranges values (3,500000,600000,0.13,'2014-09-12'); 
insert into public.test_ranges values (3,585969,999999999,0.02,'2015-11-02'); 
insert into public.test_ranges values (3,600000,670000,0.12,'2014-09-12'); 

select * from public.test_ranges order by 1,2; 

Dieser Code zurück:

category lower_bound upper_bound cost modifieddate 
-------------------------------------------------- 
1   0   70456  0  2015-09-29 
1   53956  60000  1.28 2015-02-11 
1   70456  90000  1.02 2015-09-29 
1   90000  120000  0.88 2015-02-11 
1   120000  999999999 0.79 2015-02-11 
2   0   48786  0  2015-11-02 
2   22500  25000  0.43 2015-02-17 
2   48786  50000  0.37 2015-11-02 
2   50000  100000  0.21 2015-02-17 
2   100000  175000  0.19 2015-02-17 
2   175000  999999999 0.17 2015-02-17 
3   0   585969  0.00 2015-11-02 
3   346667  375000  0.15 2014-09-12 
3   375000  500000  0.14 2014-09-12 
3   500000  600000  0.13 2014-09-12 
3   585969  999999999 0.02 2015-11-02 
3   600000  670000  0.12 2014-09-12 

Das gewünschte Ergebnis:

category lower_bound upper_bound cost modifieddate 
-------------------------------------------------- 
1   0   70456  0  2015-09-29 
1   70456  90000  1.02 2015-09-29 
1   90000  120000  0.88 2015-02-11 
1   120000  999999999 0.79 2015-02-11 
2   0   48786  0  2015-11-02 
2   48786  50000  0.37 2015-11-02 
2   50000  100000  0.21 2015-02-17 
2   100000  175000  0.19 2015-02-17 
2   175000  999999999 0.17 2015-02-17 
3   0   585969  0.00 2015-11-02 
3   585969  999999999 0.02 2015-11-02 

Vielen Dank im Voraus für jede Hilfe.

+0

Redshift oder Postgres? –

+0

Redshift ........ – Josh

+0

Könnten Sie bitte Ihre Anforderungen klären? Wollen Sie sagen, dass Zeilen, die vollständig in anderen Zeilen enthalten sind, nicht angezeigt werden sollten? Was passiert, wenn sich die Zeilen teilweise überlappen (z. B. 1-10 und 5-15)? Außerdem nehme ich an, dass der Wert für den oberen Wert nicht im Bereich enthalten ist ("kleiner als" und nicht "kleiner oder gleich"). –

Antwort

0

Sie können es ohne rekursive allgemeine Tabellenausdrücke nicht perfekt machen. Sie werden derzeit in Redshift nicht unterstützt.

Teillösung (Sie werden nicht korrekte Ergebnisse liefern für die Kategorie 3):

select tr1.* 
from public.test_ranges tr1 
    left join public.test_ranges tr_left on tr1.category = tr_left.category and tr1.lower_bound = tr_left.upper_bound 
    left join public.test_ranges tr_right on tr1.category = tr_right.category and tr_right.lower_bound = tr1.upper_bound 
where tr1.lower_bound = 0 or tr1.upper_bound = 999999999 or (tr_left.upper_bound is not null and tr_right.lower_bound is not null) 
order by tr1.category, tr1.lower_bound; 
Verwandte Themen