2016-04-11 12 views
0

In Anbetracht der unten aufgeführten Daten verknüpften Datensätze ConTrain, wie nur Datensätze auszuwählen, für die gilt:Oracle SQL - Wie zeitlichen

a) mindestens 1 vorherige Ticket für den gleichen client_id existiert und

b) Die maximale Zeitdifferenz jedes Vorgängertickets darf 14 Tage nicht überschreiten. Mit anderen Worten, wenn ein Ticket wie in a) beschrieben einen Nachfolger hat und dieser Nachfolger> 14 Tage später erstellt wurde, muss es nicht berücksichtigt werden.

create table tickets (
ticket_id number, 
client_id number, 
start_time date); 

insert into tickets values (1,1,to_date('201601011330','yyyymmddhh24mi')); 
insert into tickets values (2,1,to_date('201601021320','yyyymmddhh24mi')); 
insert into tickets values (3,1,to_date('201601101330','yyyymmddhh24mi')); 
insert into tickets values (4,1,to_date('201603101330','yyyymmddhh24mi')); 
insert into tickets values (5,2,to_date('201601011630','yyyymmddhh24mi')); 
insert into tickets values (6,2,to_date('201601201330','yyyymmddhh24mi')); 
insert into tickets values (7,3,to_date('201602011330','yyyymmddhh24mi')); 
insert into tickets values (8,4,to_date('201602290000','yyyymmddhh24mi')); 
insert into tickets values (9,4,to_date('201603011630','yyyymmddhh24mi')); 
insert into tickets values (10,4,to_date('201604011120','yyyymmddhh24mi')); 
insert into tickets values(11,4,to_date('201604101030','yyyymmddhh24mi')); 
commit; 

Antwort

1

Auch ohne Analysefunktionen möglich.

select * from tickets t1 
    where exists (
    select 1 from tickets t2 
     where t1.client_id = t2.client_id 
     and t1.start_time>t2.start_time 
     and t1.start_time<=t2.start_time+14 
    ); 
1

Sie können mit analytischen Funktionen machen, was Sie wollen. Ich denke, das ist die Logik:

select t.* 
from (select t.*, 
      row_number() over (partition by client_id order by start_time) as seqnum, 
      lag(start_time) over (partition by client_id order by start_time) as prev_st 
     from tickets t 
    ) t 
where (start_time - prev_st) < 14 and seqnum >= 2; 

Ich weiß, dass ich nicht weiß, was die „es“ verweist in (b) - der Nachfolger der den Rekord in Frage. Wie geschrieben, ist seqnum >= 2 redundant, weil der erste Datensatz für jeden Client die erste Bedingung nicht erfüllt (prev_st ist NULL). Wenn das nicht genau das ist, was Sie brauchen, dann scheint eine Kombination aus row_number(), lag() und lead() korrekt zu sein.