Oracle SQL - 如何按时间包含相关记录
Oracle SQL - How to contrain related records timewise
给出下面列出的数据,如何select只记录,其中:
a) 至少有一张相同 client_id 的先前门票存在并且
b) 每张先行票的最大时间差不得超过14天。换句话说,如果工单有 a) 中描述的后继者,并且此后继者是在 >14 天后创建的,则不得考虑。
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;
你可以用解析函数做你想做的事。我认为是这样的逻辑:
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;
我意识到我不知道 (b) 中的 "it" 指的是什么 -- 相关记录的后继者。正如所写,seqnum >= 2
是多余的,因为每个客户端的第一条记录都没有满足第一个条件(prev_st
是 NULL
)。
如果这不是您所需要的,那么 row_number()
、lag()
和 lead()
的某种组合似乎是正确的。
没有解析函数也可以。
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
);
给出下面列出的数据,如何select只记录,其中:
a) 至少有一张相同 client_id 的先前门票存在并且
b) 每张先行票的最大时间差不得超过14天。换句话说,如果工单有 a) 中描述的后继者,并且此后继者是在 >14 天后创建的,则不得考虑。
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;
你可以用解析函数做你想做的事。我认为是这样的逻辑:
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;
我意识到我不知道 (b) 中的 "it" 指的是什么 -- 相关记录的后继者。正如所写,seqnum >= 2
是多余的,因为每个客户端的第一条记录都没有满足第一个条件(prev_st
是 NULL
)。
如果这不是您所需要的,那么 row_number()
、lag()
和 lead()
的某种组合似乎是正确的。
没有解析函数也可以。
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
);