对于每个ID,我想标记接下来3天的记录。对于不在3天内的任何记录,它再次从1开始。 我不想使用循环,因为它可能会降低性能。
我的表格如下
Id Date Flag
-------------------------------------------
1 Jan 1st 1 (starting record for id 1. Any record with Jan 2nd - Jan 4th will be set to 0)
1 Jan 3rd 0 (From Jan 1st, it is within 3 days)
1 Jan 5th 1 (From Jan 1st, it is NOT within 3 days. So flag as 1.
Any record with Jan 6th - Jan 8th will be set to 0)
1 Jan 6th 0 (From Jan 5th, it is within 3 days)
2 Jan 15th 1 (Starting record for id 2)
2 Jan 17th 0 (From Jan 15th, it is within 3 days)
2 Jan 19th 1 (From Jan 15th, it is NOT within 3 days. So flag as 1)
答案 0 :(得分:1)
编辑:这个答案不正确
测试案例1:
with src as (
select 1 as id, date '2014-01-01' as d, 1 as test from dual
union all select 1, date '2014-01-03', 0 from dual
union all select 1, date '2014-01-05', 1 from dual
union all select 1, date '2014-01-06', 0 from dual
union all select 2, date '2014-01-15', 1 from dual
union all select 2, date '2014-01-17', 0 from dual
union all select 2, date '2014-01-19', 1 from dual)
,q as (
select src.*
,first_value(d)
over (partition by id
order by d
range numtodsinterval(3, 'day') preceding
) as d1
from src)
select q.id, to_char(q.d,'DD/MM/YYYY') as d
,case when q.d1 =
lag(q.d1)
over (partition by id order by d)
then 0
else 1
end as flag
,test
from q
order by id, d;
结果(测试通过):
id d flag test
== ========== ==== ====
1 01/01/2014 1 1
1 03/01/2014 0 0
1 05/01/2014 1 1
1 06/01/2014 0 0
2 15/01/2014 1 1
2 17/01/2014 0 0
2 19/01/2014 1 1
测试案例2:
with src as (
select 1 as id, date '2014-01-12' as d, 1 as test from dual
union all select 1, date '2014-01-13', 0 from dual
union all select 1, date '2014-01-15', 0 from dual
union all select 1, date '2014-01-18', 1 from dual
union all select 1, date '2014-01-21', 0 from dual
union all select 1, date '2014-02-02', 1 from dual
union all select 1, date '2014-02-03', 0 from dual
union all select 1, date '2014-02-09', 1 from dual
union all select 1, date '2014-02-10', 0 from dual
union all select 1, date '2014-02-11', 0 from dual
union all select 1, date '2014-02-18', 1 from dual
union all select 1, date '2014-02-21', 0 from dual)
,q as (
select src.*
,first_value(d)
over (partition by id
order by d
range numtodsinterval(3, 'day') preceding
) as d1
from src)
select q.id, to_char(q.d,'DD/MM/YYYY') as d
,case when q.d1 =
lag(q.d1)
over (partition by id order by d)
then 0
else 1
end as flag
,test
from q
order by id, d;
结果(测试失败):
id d flag test
== ========== ==== ====
1 12/01/2014 1 1
1 13/01/2014 0 0
1 15/01/2014 0 0
1 18/01/2014 1 1
1 21/01/2014 1 0 <--- test failed
1 02/02/2014 1 1
1 03/02/2014 0 0
1 09/02/2014 1 1
1 10/02/2014 0 0
1 11/02/2014 0 0
1 18/02/2014 1 1
1 21/02/2014 0 0